PageRenderTime 44ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/fuel/packages/orm/classes/belongsto.php

https://bitbucket.org/arkross/venus
PHP | 211 lines | 170 code | 23 blank | 18 comment | 16 complexity | 1bd84f0ab15b24802fc9b0b942cfcd7d MD5 | raw file
Possible License(s): MIT, BSD-3-Clause
  1. <?php
  2. /**
  3. * Fuel is a fast, lightweight, community driven PHP5 framework.
  4. *
  5. * @package Fuel
  6. * @version 1.0
  7. * @author Fuel Development Team
  8. * @license MIT License
  9. * @copyright 2010 - 2011 Fuel Development Team
  10. * @link http://fuelphp.com
  11. */
  12. namespace Orm;
  13. class BelongsTo extends Relation
  14. {
  15. protected $singular = true;
  16. protected $key_from = array();
  17. protected $key_to = array('id');
  18. public function __construct($from, $name, array $config)
  19. {
  20. $this->name = $name;
  21. $this->model_from = $from;
  22. $this->model_to = array_key_exists('model_to', $config)
  23. ? $config['model_to'] : \Inflector::get_namespace($from).'Model_'.\Inflector::classify($name);
  24. $this->key_from = array_key_exists('key_from', $config)
  25. ? (array) $config['key_from'] : (array) \Inflector::foreign_key($this->model_to);
  26. $this->key_to = array_key_exists('key_to', $config)
  27. ? (array) $config['key_to'] : $this->key_to;
  28. $this->conditions = array_key_exists('conditions', $config)
  29. ? (array) $config['conditions'] : array();
  30. $this->cascade_save = array_key_exists('cascade_save', $config)
  31. ? $config['cascade_save'] : $this->cascade_save;
  32. $this->cascade_delete = array_key_exists('cascade_delete', $config)
  33. ? $config['cascade_delete'] : $this->cascade_delete;
  34. if ( ! class_exists($this->model_to))
  35. {
  36. throw new \FuelException('Related model not found by Belongs_To relation "'.$this->name.'": '.$this->model_to);
  37. }
  38. $this->model_to = get_real_class($this->model_to);
  39. }
  40. public function get(Model $from)
  41. {
  42. $query = call_user_func(array($this->model_to, 'find'));
  43. reset($this->key_to);
  44. foreach ($this->key_from as $key)
  45. {
  46. $query->where(current($this->key_to), $from->{$key});
  47. next($this->key_to);
  48. }
  49. return $query->get_one();
  50. }
  51. public function join($alias_from, $rel_name, $alias_to_nr, $conditions = array())
  52. {
  53. $alias_to = 't'.$alias_to_nr;
  54. $model = array(
  55. 'model' => $this->model_to,
  56. 'connection' => call_user_func(array($this->model_to, 'connection')),
  57. 'table' => array(call_user_func(array($this->model_to, 'table')), $alias_to),
  58. 'primary_key' => call_user_func(array($this->model_to, 'primary_key')),
  59. 'join_type' => \Arr::get($conditions, 'join_type') ?: \Arr::get($this->conditions, 'join_type', 'left'),
  60. 'join_on' => array(),
  61. 'columns' => $this->select($alias_to),
  62. 'rel_name' => strpos($rel_name, '.') ? substr($rel_name, strrpos($rel_name, '.') + 1) : $rel_name,
  63. 'relation' => $this,
  64. 'where' => \Arr::get($conditions, 'where', array()),
  65. 'order_by' => \Arr::get($conditions, 'order_by') ?: \Arr::get($this->conditions, 'order_by', array()),
  66. );
  67. reset($this->key_to);
  68. foreach ($this->key_from as $key)
  69. {
  70. $model['join_on'][] = array($alias_from.'.'.$key, '=', $alias_to.'.'.current($this->key_to));
  71. next($this->key_to);
  72. }
  73. foreach (\Arr::get($this->conditions, 'where', array()) as $key => $condition)
  74. {
  75. ! is_array($condition) and $condition = array($key, '=', $condition);
  76. if ( ! $condition[0] instanceof \Fuel\Core\Database_Expression and strpos($condition[0], '.') === false)
  77. {
  78. $condition[0] = $alias_to.'.'.$condition[0];
  79. }
  80. is_string($condition[2]) and $condition[2] = \Db::quote($condition[2], $model['connection']);
  81. $model['join_on'][] = $condition;
  82. }
  83. return array($rel_name => $model);
  84. }
  85. public function save($model_from, $model_to, $original_model_id, $parent_saved, $cascade)
  86. {
  87. if ($parent_saved)
  88. {
  89. return;
  90. }
  91. if ( ! $model_to instanceof $this->model_to and $model_to !== null)
  92. {
  93. throw new \FuelException('Invalid Model instance added to relations in this model.');
  94. }
  95. // Save if it's a yet unsaved object
  96. if ($model_to and $model_to->is_new())
  97. {
  98. $model_to->save(false);
  99. }
  100. $current_model_id = $model_to ? $model_to->implode_pk($model_to) : null;
  101. // Check if there was another model assigned (this supersedes any change to the foreign key(s))
  102. if ($current_model_id != $original_model_id)
  103. {
  104. // change the foreign keys in the model_from to point to the new relation
  105. reset($this->key_from);
  106. $model_from->unfreeze();
  107. foreach ($this->key_to as $pk)
  108. {
  109. $model_from->{current($this->key_from)} = $model_to ? $model_to->{$pk} : null;
  110. next($this->key_from);
  111. }
  112. $model_from->freeze();
  113. }
  114. // if not check the model_from's foreign_keys
  115. else
  116. {
  117. $foreign_keys = count($this->key_to) == 1 ? array($original_model_id) : explode('][', substr($original_model_id, 1, -1));
  118. $changed = false;
  119. $new_rel_id = array();
  120. reset($foreign_keys);
  121. foreach ($this->key_from as $fk)
  122. {
  123. if (is_null($model_from->{$fk}))
  124. {
  125. $changed = true;
  126. $new_rel_id = null;
  127. break;
  128. }
  129. elseif ($model_from->{$fk} != current($foreign_keys))
  130. {
  131. $changed = true;
  132. }
  133. $new_rel_id[] = $model_from->{$fk};
  134. next($foreign_keys);
  135. }
  136. // if any of the keys changed, reload the relationship - saving the object will save those keys
  137. if ($changed)
  138. {
  139. // Attempt to load the new related object
  140. if ( ! is_null($new_rel_id))
  141. {
  142. $rel_obj = call_user_func(array($this->model_to, 'find'), $new_rel_id);
  143. if (empty($rel_obj))
  144. {
  145. throw new \FuelException('New relation set on '.$this->model_from.' object wasn\'t found.');
  146. }
  147. }
  148. else
  149. {
  150. $rel_obj = null;
  151. }
  152. // Add the new relation to the model_from
  153. $model_from->unfreeze();
  154. $rel = $model_from->_relate();
  155. $rel[$this->name] = $rel_obj;
  156. $model_from->_relate($rel);
  157. $model_from->freeze();
  158. }
  159. }
  160. $cascade = is_null($cascade) ? $this->cascade_save : (bool) $cascade;
  161. if ($cascade and ! empty($model_to))
  162. {
  163. $model_to->save();
  164. }
  165. }
  166. public function delete($model_from, $model_to, $parent_deleted, $cascade)
  167. {
  168. if ($parent_deleted)
  169. {
  170. return;
  171. }
  172. // break current relations
  173. $model_from->unfreeze();
  174. $rels = $model_from->_relate();
  175. $rels[$this->name] = null;
  176. $model_from->_relate($rels);
  177. foreach ($this->key_from as $fk)
  178. {
  179. $model_from->{$fk} = null;
  180. }
  181. $model_from->freeze();
  182. $cascade = is_null($cascade) ? $this->cascade_delete : (bool) $cascade;
  183. if ($cascade and ! empty($model_to))
  184. {
  185. $model_to->delete();
  186. }
  187. }
  188. }