relationship.class.php 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. <?php
  2. namespace Juju\ORM {
  3. require_once(realpath(dirname(__DIR__).'/earray.class.php'));
  4. use \Juju\EArray;
  5. use \Juju\ORM;
  6. class Relationship extends EArray {
  7. private $model;
  8. private $name;
  9. private $alias;
  10. private $removed = [];
  11. private $added = [];
  12. public static function from(ORM $model, string $name, array $alias, array $data){
  13. $earray = parent::from($data);
  14. $earray->model = $model;
  15. $earray->name = $name;
  16. $earray->alias = $alias;
  17. return $earray
  18. ->on('set', function(&$offset, &$value) use($earray){
  19. $earray->added = array_merge($earray->added, [$value]);
  20. $earray->removed = array_diff($earray->removed, [$value]);
  21. })->on('unset', function($offset, $value) use($earray){
  22. $earray->removed = array_merge($earray->removed, [$value]);
  23. $earray->added = array_diff($earray->added, [$value]);
  24. });
  25. }
  26. public function add(ORM $model){
  27. $this[] = $model;
  28. return $this;
  29. }
  30. public function remove(ORM $model){
  31. $index = $this->index($model);
  32. if($index !== false){
  33. unset($this->data[$index]);
  34. }
  35. return $this;
  36. }
  37. public function has(ORM $model){
  38. return $this->index($model) !== false;
  39. }
  40. public function index(ORM $model){
  41. return array_search($model, $this->data);
  42. }
  43. public function dirty(){
  44. return count($this->removed) + count($this->added) > 0;
  45. }
  46. public function reset(){
  47. foreach($this->added as $model){
  48. $index = array_search($model, $this->data);
  49. if($index !== false){
  50. unset($this->data[$index]);
  51. }
  52. }
  53. $this->added = [];
  54. foreach($this->removed as $model){
  55. $this->data = array_merge($this->data, [$model]);
  56. }
  57. $this->removed = [];
  58. }
  59. public function save(){
  60. if($this->dirty()){
  61. $model = $this->model;
  62. $alias = $this->$alias;
  63. $name = $this->name;
  64. $class = "\\Models\\{$alias['model']}";
  65. if(isset($model->has_many[$name])){
  66. throw new \Exception("Invalid relationship {$name}");
  67. }
  68. if(isset($alias['through'])){
  69. $rem_sql = "delete from {$alias['through']} where {$alias['foreign_key']} = ? and ".$class::table_name().$class::foreign_key_suffix()." = ?";
  70. $rem_args = [$model->id];
  71. $add_sql = "insert into {$alias['through']} ({$alias['foreign_key']}, ".$class::table_name().$class::foreign_key_suffix().") values (?, ?)";
  72. }else{
  73. $rem_sql = "update {$alias['model']} set {$alias['foreign_key']} = null where ".$class::primary_key()." = ?";
  74. $rem_args = [];
  75. $add_sql .= "update {$alias['model']} set {$alias['foreign_key']} = ? where ".$class::primary_key()." = ?";
  76. }
  77. $class = get_class($models);
  78. foreach($this->removed as $item){
  79. $class::query(
  80. $rem_sql,
  81. 'ii',
  82. ...array_merge($rem_args, [$item->id])
  83. )->execute();
  84. }
  85. $this->removed = [];
  86. foreach($this->added as $item){
  87. $class::query(
  88. $add_sql,
  89. 'ii',
  90. $model->id,
  91. $item->id
  92. )->execute();
  93. }
  94. $this->added = [];
  95. }
  96. }
  97. }
  98. }
  99. ?>