PageRenderTime 112ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

/solar/source/miku/Miku/Filter/SanitizeBelongsTo.php

https://bitbucket.org/Sanakan/noise
PHP | 114 lines | 74 code | 14 blank | 26 comment | 13 complexity | ff05bd5d8d91501353bf476b0ca9f1a0 MD5 | raw file
Possible License(s): MIT
  1. <?php
  2. /* prepare the related col, witch should be unique
  3. * @param String $col Unique col in the foreign
  4. * @param String $foreign_alias Belongs to's foreign_alias, used to insert a new parent record if not exist
  5. * @param String $cache_col Cache col in the foreign
  6. * @param Mix $where Additional "WHERE" conditions to exclude records from the uniqueness check.
  7. * @return Null
  8. */
  9. class Miku_Filter_SanitizeBelongsTo extends Solar_Filter_Abstract
  10. {
  11. //$this->_addFilter('_foo', 'sanitizeBelongsTo');
  12. public function sanitizeBelongsTo($value, $col, $foreign_alias, $cache_col = null, $where = null)
  13. {
  14. if(! is_array($value)) {
  15. throw $this->_exception('ERR_NOT_ARRAY_VALUE');
  16. }
  17. $record = $this->_filter->getData();
  18. if (! $record instanceof Solar_Sql_Model_Record) {
  19. throw $this->_exception('ERR_NOT_MODEL_RECORD');
  20. }
  21. $key = $this->_filter->getDataKey();
  22. $key = substr($key, 1);
  23. $native = $record->getModel();
  24. if(empty($native->related[$key])) {
  25. throw $this->_exception('ERR_NOT_RELATED_VANLUE');
  26. }
  27. $related = $native->getRelated($key);
  28. $foreign = $related->getModel();
  29. settype($where, 'array');
  30. // the column we're validating as unique. what we do is select the
  31. // current value from the database, and if it's there, that means
  32. // the current value is not unique. we'll add exclusion conditions
  33. // below.
  34. $where[] = "$col = :$col";
  35. // what is the primary-key column for the record model?
  36. $primary = $foreign->primary_col;
  37. // only add a primary key exclusion if the column being validated
  38. // is not itself the primary key.
  39. if ($col != $primary) {
  40. // exclude the current record by its primary key value.
  41. if (! isset($value[$primary])) {
  42. $where[] = "$primary IS NOT NULL";
  43. } else {
  44. $where[] = "$primary != :$primary";
  45. }
  46. }
  47. if($cache_col) {
  48. $result = $foreign->fetchOne(array(
  49. 'where' => $where,
  50. 'cols' => array($primary, $cache_col),
  51. 'bind' => $value,
  52. ));
  53. }else {
  54. // see if we can fetch a row, with only the primary-key column to
  55. // reduce resource usage.
  56. $result = $foreign->fetchOne(array(
  57. 'where' => $where,
  58. 'cols' => array($primary),
  59. 'bind' => $value,
  60. ));
  61. }
  62. $old = $record->$key;
  63. // if empty, no result was returned, so the value haven't been set , and need insert
  64. if(empty($result)) {
  65. if($cache_col) {
  66. $value[$cache_col] = 1;
  67. if(isset($old->$primary)) {
  68. //count down the old
  69. $foreign->update(
  70. array($cache_col => (int)$old->$cache_col - 1),
  71. array("$primary = ?" => $old->$primary)
  72. );
  73. }
  74. }
  75. $id = $foreign->insert($value);
  76. $native_col = $related->native_col;
  77. $record[$native_col] = $id;
  78. //if already exist
  79. }elseif ($cache_col) {
  80. if($old->$primary !== $result->$primary){
  81. //count down the old
  82. $foreign->update(
  83. array($cache_col => (int)$old->$cache_col - 1),
  84. array("$primary = ?" => $old->$primary)
  85. );
  86. //count up the new
  87. $foreign->update(
  88. array($cache_col => (int)$result->$cache_col + 1),
  89. array("$primary = ?" => $result->$primary)
  90. );
  91. $native_col = $related->native_col;
  92. $record[$native_col] = $result->$primary;
  93. }
  94. }
  95. // noneed to retain the sanitized value to the related key
  96. // see Solar_Sql_Model_Record::_save
  97. // http://php.net/manual/en/function.empty.php
  98. return null;
  99. }
  100. }