relationship.class.php 2.9 KB

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