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

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

https://bitbucket.org/codeyash/bootstrap
PHP | 221 lines | 179 code | 23 blank | 19 comment | 17 complexity | 8337b5ba952baea0efdfb73c001de23d MD5 | raw file
Possible License(s): MIT, Apache-2.0
  1. <?php
  2. /**
  3. * Fuel is a fast, lightweight, community driven PHP5 framework.
  4. *
  5. * @package Fuel
  6. * @version 1.5
  7. * @author Fuel Development Team
  8. * @license MIT License
  9. * @copyright 2010 - 2013 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, 'query'));
  43. reset($this->key_to);
  44. foreach ($this->key_from as $key)
  45. {
  46. // no point running a query when a key value is null
  47. if ($from->{$key} === null)
  48. {
  49. return null;
  50. }
  51. $query->where(current($this->key_to), $from->{$key});
  52. next($this->key_to);
  53. }
  54. foreach (\Arr::get($this->conditions, 'where', array()) as $key => $condition)
  55. {
  56. is_array($condition) or $condition = array($key, '=', $condition);
  57. $query->where($condition);
  58. }
  59. return $query->get_one();
  60. }
  61. public function join($alias_from, $rel_name, $alias_to_nr, $conditions = array())
  62. {
  63. $alias_to = 't'.$alias_to_nr;
  64. $model = array(
  65. 'model' => $this->model_to,
  66. 'connection' => call_user_func(array($this->model_to, 'connection')),
  67. 'table' => array(call_user_func(array($this->model_to, 'table')), $alias_to),
  68. 'primary_key' => call_user_func(array($this->model_to, 'primary_key')),
  69. 'join_type' => \Arr::get($conditions, 'join_type') ?: \Arr::get($this->conditions, 'join_type', 'left'),
  70. 'join_on' => array(),
  71. 'columns' => $this->select($alias_to),
  72. 'rel_name' => strpos($rel_name, '.') ? substr($rel_name, strrpos($rel_name, '.') + 1) : $rel_name,
  73. 'relation' => $this,
  74. 'where' => \Arr::get($conditions, 'where', array()),
  75. 'order_by' => \Arr::get($conditions, 'order_by') ?: \Arr::get($this->conditions, 'order_by', array()),
  76. );
  77. reset($this->key_to);
  78. foreach ($this->key_from as $key)
  79. {
  80. $model['join_on'][] = array($alias_from.'.'.$key, '=', $alias_to.'.'.current($this->key_to));
  81. next($this->key_to);
  82. }
  83. foreach (\Arr::get($this->conditions, 'where', array()) as $key => $condition)
  84. {
  85. ! is_array($condition) and $condition = array($key, '=', $condition);
  86. if ( ! $condition[0] instanceof \Fuel\Core\Database_Expression and strpos($condition[0], '.') === false)
  87. {
  88. $condition[0] = $alias_to.'.'.$condition[0];
  89. }
  90. is_string($condition[2]) and $condition[2] = \Db::quote($condition[2], $model['connection']);
  91. $model['join_on'][] = $condition;
  92. }
  93. return array($rel_name => $model);
  94. }
  95. public function save($model_from, $model_to, $original_model_id, $parent_saved, $cascade)
  96. {
  97. if ($parent_saved)
  98. {
  99. return;
  100. }
  101. if ( ! $model_to instanceof $this->model_to and $model_to !== null)
  102. {
  103. throw new \FuelException('Invalid Model instance added to relations in this model.');
  104. }
  105. // Save if it's a yet unsaved object
  106. if ($model_to and $model_to->is_new())
  107. {
  108. $model_to->save(false);
  109. }
  110. $current_model_id = $model_to ? $model_to->implode_pk($model_to) : null;
  111. // Check if there was another model assigned (this supersedes any change to the foreign key(s))
  112. if ($current_model_id != $original_model_id)
  113. {
  114. // change the foreign keys in the model_from to point to the new relation
  115. reset($this->key_from);
  116. $model_from->unfreeze();
  117. foreach ($this->key_to as $pk)
  118. {
  119. $model_from->{current($this->key_from)} = $model_to ? $model_to->{$pk} : null;
  120. next($this->key_from);
  121. }
  122. $model_from->freeze();
  123. }
  124. // if not check the model_from's foreign_keys
  125. else
  126. {
  127. $foreign_keys = count($this->key_to) == 1 ? array($original_model_id) : explode('][', substr($original_model_id, 1, -1));
  128. $changed = false;
  129. $new_rel_id = array();
  130. reset($foreign_keys);
  131. foreach ($this->key_from as $fk)
  132. {
  133. if (is_null($model_from->{$fk}))
  134. {
  135. $changed = true;
  136. $new_rel_id = null;
  137. break;
  138. }
  139. elseif ($model_from->{$fk} != current($foreign_keys))
  140. {
  141. $changed = true;
  142. }
  143. $new_rel_id[] = $model_from->{$fk};
  144. next($foreign_keys);
  145. }
  146. // if any of the keys changed, reload the relationship - saving the object will save those keys
  147. if ($changed)
  148. {
  149. // Attempt to load the new related object
  150. if ( ! is_null($new_rel_id))
  151. {
  152. $rel_obj = call_user_func(array($this->model_to, 'find'), $new_rel_id);
  153. if (empty($rel_obj))
  154. {
  155. throw new \FuelException('New relation set on '.$this->model_from.' object wasn\'t found.');
  156. }
  157. }
  158. else
  159. {
  160. $rel_obj = null;
  161. }
  162. // Add the new relation to the model_from
  163. $model_from->unfreeze();
  164. $rel = $model_from->_relate();
  165. $rel[$this->name] = $rel_obj;
  166. $model_from->_relate($rel);
  167. $model_from->freeze();
  168. }
  169. }
  170. $cascade = is_null($cascade) ? $this->cascade_save : (bool) $cascade;
  171. if ($cascade and ! empty($model_to))
  172. {
  173. $model_to->save();
  174. }
  175. }
  176. public function delete($model_from, $model_to, $parent_deleted, $cascade)
  177. {
  178. if ($parent_deleted)
  179. {
  180. return;
  181. }
  182. // break current relations
  183. $model_from->unfreeze();
  184. $rels = $model_from->_relate();
  185. $rels[$this->name] = null;
  186. $model_from->_relate($rels);
  187. foreach ($this->key_from as $fk)
  188. {
  189. $model_from->{$fk} = null;
  190. }
  191. $model_from->freeze();
  192. $cascade = is_null($cascade) ? $this->cascade_delete : (bool) $cascade;
  193. if ($cascade and ! empty($model_to))
  194. {
  195. $model_to->delete();
  196. }
  197. }
  198. }