Completed
Push — master ( a73a07...f2b62d )
by Peter
05:49
created

AbstractScopeManager::apply()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 18
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 4.016

Importance

Changes 0
Metric Value
dl 0
loc 18
ccs 9
cts 10
cp 0.9
rs 9.2
c 0
b 0
f 0
cc 4
eloc 10
nc 5
nop 1
crap 4.016
1
<?php
2
3
namespace Maslosoft\Mangan\Abstracts;
4
5
use Maslosoft\Mangan\Document;
6
use Maslosoft\Mangan\Interfaces\Criteria\DecoratableInterface;
7
use Maslosoft\Mangan\Interfaces\CriteriaAwareInterface;
8
use Maslosoft\Mangan\Interfaces\CriteriaInterface;
9
use Maslosoft\Mangan\Interfaces\ModelAwareInterface;
10
use Maslosoft\Mangan\Interfaces\ScopeManagerInterface;
11
use Maslosoft\Mangan\Interfaces\WithCriteriaInterface;
12
use Maslosoft\Mangan\Traits\ModelAwareTrait;
13
14
/**
15
 * Base class for implementing scope managers
16
 *
17
 * @see ScopeManagerInterface
18
 * @author Piotr Maselkowski <pmaselkowski at gmail.com>
19
 */
20
abstract class AbstractScopeManager implements ModelAwareInterface
21
{
22
23
	use ModelAwareTrait;
24
25
	/**
26
	 *
27
	 * @var CriteriaInterface
28
	 */
29
	private $criteria = null;
30
31
	/**
32
	 * Returns the declaration of named scopes.
33
	 * A named scope represents a query criteria that can be chained together with
34
	 * other named scopes and applied to a query. This method should be overridden
35
	 * by child classes to declare named scopes for the particular document classes.
36
	 * For example, the following code declares two named scopes: 'recently' and
37
	 * 'published'.
38
	 * <pre>
39
	 * return array(
40
	 * 	'published'=>array(
41
	 * 		'conditions'=>array(
42
	 * 				'status'=>array('==', 1),
43
	 * 		),
44
	 * 	),
45
	 * 	'recently'=>array(
46
	 * 		'sort'=>array('create_time'=>Criteria::SortDesc),
47
	 * 		'limit'=>5,
48
	 * 	),
49
	 * );
50
	 * </pre>
51
	 * If the above scopes are declared in a 'Post' model, we can perform the following
52
	 * queries:
53
	 * <pre>
54
	 * $posts=Post::model()->published()->findAll();
55
	 * $posts=Post::model()->published()->recently()->findAll();
56
	 * $posts=Post::model()->published()->published()->recently()->find();
57
	 * </pre>
58
	 *
59
	 * @return array the scope definition. The array keys are scope names; the array
60
	 * values are the corresponding scope definitions. Each scope definition is represented
61
	 * as an array whose keys must be properties of {@link Criteria}.
62
	 * @since v1.0
63
	 */
64
	public function scopes()
65
	{
66
		return [];
67
	}
68
69
	/**
70
	 * Returns the default named scope that should be implicitly applied to all queries for this model.
71
	 * Note, default scope only applies to SELECT queries. It is ignored for INSERT, UPDATE and DELETE queries.
72
	 * The default implementation simply returns an empty array. You may override this method
73
	 * if the model needs to be queried with some default criteria (e.g. only active records should be returned).
74
	 * @return array the mongo criteria. This will be used as the parameter to the constructor
75
	 * of {@link Criteria}.
76
	 * @since v1.2.2
77
	 */
78
	public function defaultScope()
79
	{
80
		return [];
81
	}
82
83
	/**
84
	 * Resets all scopes and criteria applied including default scope.
85
	 *
86
	 * @return Document
87
	 * @since v1.0
88
	 */
89
	public function resetScope()
90
	{
91
		$this->criteria = $this->getNewCriteria();
92
		return $this;
93
	}
94
95
	/**
96
	 * Apply scopes to criteria, will create criteria object if not provided and pass it by reference
97
	 * @param CriteriaInterface|array|null $criteria
98
	 * @return CriteriaInterface
99
	 */
100 86
	public function apply(&$criteria = null)
101
	{
102 86
		if (null === $criteria)
103
		{
104 24
			return $this->getModelCriteria();
105
		}
106 81
		elseif (is_array($criteria))
107
		{
108
			$criteria = $this->getNewCriteria($criteria);
109
		}
110 81
		$criteria->mergeWith($this->criteria);
111 81
		$criteria->mergeWith($this->getModelCriteria());
112 81
		if ($criteria instanceof DecoratableInterface)
113
		{
114 81
			$criteria->decorateWith($this->getModel());
115
		}
116 81
		return $criteria;
117
	}
118
119
	public function reset()
120
	{
121
		$this->criteria = $this->getNewCriteria();
122
		return $this;
123
	}
124
125 86
	protected function getModelCriteria()
126
	{
127 86
		$criteria = null;
128 86
		if ($this->model instanceof WithCriteriaInterface)
129
		{
130 29
			$criteria = $this->model->getDbCriteria();
131
		}
132 57
		elseif ($this->model instanceof CriteriaAwareInterface)
133
		{
134
			$criteria = $this->model->getCriteria();
135
		}
136 86
		if (empty($criteria))
137
		{
138 57
			return $this->getNewCriteria();
139
		}
140 29
		return $criteria;
141
	}
142
143
	abstract public function getNewCriteria($criteria = null);
144
}
145