Completed
Push — master ( 2d3c47...157dd8 )
by Chris
03:55
created

Has::save()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 15
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 8
nc 3
nop 1
dl 0
loc 15
rs 9.2
c 0
b 0
f 0
1
<?php
2
namespace Darya\ORM\Relation;
3
4
use Exception;
5
use Darya\ORM\Record;
6
use Darya\ORM\Relation;
7
8
/**
9
 * Darya's has-one entity relation.
10
 * 
11
 * @author Chris Andrew <[email protected]>
12
 */
13
class Has extends Relation
14
{
15
	/**
16
	 * Set the default keys for the relation if they have not yet been set.
17
	 */
18
	protected function setDefaultKeys()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
19
	{
20
		if (!$this->foreignKey) {
21
			$this->foreignKey = $this->prepareForeignKey(get_class($this->parent));
22
		}
23
		
24
		$this->localKey = $this->parent->key();
25
	}
26
	
27
	/**
28
	 * Eagerly load the related models for the given parent instances.
29
	 * 
30
	 * Returns the given instances with their related models loaded.
31
	 * 
32
	 * @param array $instances
33
	 * @return array
34
	 */
35 View Code Duplication
	public function eager(array $instances)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
36
	{
37
		$this->verifyParents($instances);
38
		$ids = static::attributeList($instances, 'id');
39
		
40
		$filter = array_merge($this->filter(), array(
41
			$this->foreignKey => array_unique($ids)
42
		));
43
		
44
		$data = $this->storage()->read($this->target->table(), $filter, $this->order());
45
		
46
		$class = get_class($this->target);
47
		$generated = $class::generate($data);
48
		
49
		$related = array();
50
		
51
		foreach ($generated as $model) {
52
			$related[$model->get($this->foreignKey)] = $model;
53
		}
54
		
55
		foreach ($instances as $instance) {
56
			$key = $instance->id();
57
			$value = isset($related[$key]) ? $related[$key] : array();
58
			$instance->relation($this->name)->set($value);
59
		}
60
		
61
		return $instances;
62
	}
63
	
64
	/**
65
	 * Retrieve the related model.
66
	 * 
67
	 * @return Record|null
68
	 */
69
	public function retrieve()
70
	{
71
		return $this->one();
72
	}
73
	
74
	/**
75
	 * Associate the given model.
76
	 * 
77
	 * Dissociates any currently associated model beforehand.
78
	 * 
79
	 * Returns the number of successfully associated models.
80
	 * 
81
	 * @param Record[]|Record $instances
82
	 * @return int
83
	 */
84 View Code Duplication
	public function associate($instances)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
85
	{
86
		$this->verify($instances);
87
		
88
		$this->dissociate();
89
		$this->attach($instances);
90
		
91
		$ids = static::attributeList($instances, 'id');
92
		
93
		$successful = 0;
94
		
95
		foreach ($this->related as $model) {
96
			$this->persist($model);
97
			
98
			if (!$ids || in_array($model->id(), $ids)) {
99
				$model->set($this->foreignKey, $this->parent->id());
100
				$successful += $model->save();
101
			}
102
		}
103
		
104
		return (int) $successful;
105
	}
106
	
107
	/**
108
	 * Dissociate the related model.
109
	 * 
110
	 * Returns true if the model was successfully dissociated.
111
	 * 
112
	 * @param Record[]|Record $instances [optional]
113
	 * @return int
114
	 */
115
	public function dissociate($instances = array())
116
	{
117
		$this->verify($instances);
118
		
119
		// Fall back to loading existing relations if none are given
120
		$associated = static::arrayify($instances) ?: $this->load(1);
121
		
122
		// Mark these models as detached
123
		$this->detach($associated);
124
		
125
		$successful = 0;
126
		
127
		// Persist the detachment of the models
128
		foreach ($this->detached as $model) {
129
			$model->set($this->foreignKey, 0);
130
			$successful += $model->save();
131
		}
132
		
133
		// Clear the set of models to detach
134
		$this->detached = array();
135
		
136
		return $successful;
137
	}
138
}
139