|
1
|
|
|
<?php |
|
2
|
|
|
/** |
|
3
|
|
|
* Spiral Framework. |
|
4
|
|
|
* |
|
5
|
|
|
* @license MIT |
|
6
|
|
|
* @author Anton Titov (Wolfy-J) |
|
7
|
|
|
*/ |
|
8
|
|
|
namespace Spiral\ODM\Entities; |
|
9
|
|
|
|
|
10
|
|
|
use Spiral\Core\Component; |
|
11
|
|
|
use Spiral\Core\Traits\SaturateTrait; |
|
12
|
|
|
use Spiral\Models\SourceInterface; |
|
13
|
|
|
use Spiral\ODM\DocumentEntity; |
|
14
|
|
|
use Spiral\ODM\Exceptions\SourceException; |
|
15
|
|
|
use Spiral\ODM\ODM; |
|
16
|
|
|
|
|
17
|
|
|
/** |
|
18
|
|
|
* Source class associated to one or multiple (default implementation) ODM models. Source can be |
|
19
|
|
|
* used to write your own custom find method or change default selection. |
|
20
|
|
|
*/ |
|
21
|
|
|
class DocumentSource extends Component implements SourceInterface, \Countable |
|
22
|
|
|
{ |
|
23
|
|
|
/** |
|
24
|
|
|
* Sugary! |
|
25
|
|
|
*/ |
|
26
|
|
|
use SaturateTrait; |
|
27
|
|
|
|
|
28
|
|
|
/** |
|
29
|
|
|
* Linked document model. ODM can automatically index and link user sources to models based on |
|
30
|
|
|
* value of this constant. |
|
31
|
|
|
*/ |
|
32
|
|
|
const DOCUMENT = null; |
|
33
|
|
|
|
|
34
|
|
|
/** |
|
35
|
|
|
* Associated document class. |
|
36
|
|
|
* |
|
37
|
|
|
* @var string |
|
38
|
|
|
*/ |
|
39
|
|
|
private $class = null; |
|
40
|
|
|
|
|
41
|
|
|
/** |
|
42
|
|
|
* @var DocumentSelector |
|
43
|
|
|
*/ |
|
44
|
|
|
private $selector = null; |
|
45
|
|
|
|
|
46
|
|
|
/** |
|
47
|
|
|
* @invisible |
|
48
|
|
|
* @var ODM |
|
49
|
|
|
*/ |
|
50
|
|
|
protected $odm = null; |
|
51
|
|
|
|
|
52
|
|
|
/** |
|
53
|
|
|
* @param string $class |
|
54
|
|
|
* @param ODM $odm |
|
55
|
|
|
* @throws SourceException |
|
56
|
|
|
*/ |
|
57
|
|
View Code Duplication |
public function __construct($class = null, ODM $odm = null) |
|
|
|
|
|
|
58
|
|
|
{ |
|
59
|
|
|
if (empty($class)) { |
|
60
|
|
|
if (empty(static::DOCUMENT)) { |
|
61
|
|
|
throw new SourceException("Unable to create source without associate class."); |
|
62
|
|
|
} |
|
63
|
|
|
|
|
64
|
|
|
$class = static::DOCUMENT; |
|
65
|
|
|
} |
|
66
|
|
|
|
|
67
|
|
|
$this->class = $class; |
|
68
|
|
|
$this->odm = $this->saturate($odm, ODM::class); |
|
69
|
|
|
$this->setSelector($this->odm->selector($this->class)); |
|
70
|
|
|
} |
|
71
|
|
|
|
|
72
|
|
|
/** |
|
73
|
|
|
* Create new DocumentEntity based on set of provided fields. |
|
74
|
|
|
* |
|
75
|
|
|
* @final Change static method of entity, not this one. |
|
76
|
|
|
* @param array $fields |
|
77
|
|
|
* @param string $class Due ODM models can be inherited you can use this argument to specify |
|
78
|
|
|
* custom model class. |
|
79
|
|
|
* @return DocumentEntity |
|
80
|
|
|
*/ |
|
81
|
|
|
final public function create($fields = [], $class = null) |
|
82
|
|
|
{ |
|
83
|
|
|
if (empty($class)) { |
|
84
|
|
|
$class = $this->class; |
|
85
|
|
|
} |
|
86
|
|
|
|
|
87
|
|
|
//Letting entity to create itself (needed |
|
88
|
|
|
return call_user_func([$class, 'create'], $fields, $this->odm); |
|
89
|
|
|
} |
|
90
|
|
|
|
|
91
|
|
|
/** |
|
92
|
|
|
* Find document by it's primary key. |
|
93
|
|
|
* |
|
94
|
|
|
* @see findOne() |
|
95
|
|
|
* @param string|\MongoId $id Primary key value. |
|
96
|
|
|
* @return DocumentEntity|null |
|
97
|
|
|
*/ |
|
98
|
|
|
public function findByPK($id) |
|
99
|
|
|
{ |
|
100
|
|
|
return $this->find()->findByPK($id); |
|
101
|
|
|
} |
|
102
|
|
|
|
|
103
|
|
|
/** |
|
104
|
|
|
* Select one document from mongo collection. |
|
105
|
|
|
* |
|
106
|
|
|
* @param array $query Fields and conditions to query by. |
|
107
|
|
|
* @param array $sortBy |
|
108
|
|
|
* @return DocumentEntity|null |
|
109
|
|
|
*/ |
|
110
|
|
|
public function findOne(array $query = [], array $sortBy = []) |
|
111
|
|
|
{ |
|
112
|
|
|
return $this->find()->sortBy($sortBy)->findOne($query); |
|
113
|
|
|
} |
|
114
|
|
|
|
|
115
|
|
|
/** |
|
116
|
|
|
* Get associated document selection with pre-configured query (if any). |
|
117
|
|
|
* |
|
118
|
|
|
* @param array $query |
|
119
|
|
|
* @return DocumentSelector |
|
120
|
|
|
*/ |
|
121
|
|
|
public function find(array $query = []) |
|
122
|
|
|
{ |
|
123
|
|
|
return $this->selector()->query($query); |
|
124
|
|
|
} |
|
125
|
|
|
|
|
126
|
|
|
/** |
|
127
|
|
|
* {@inheritdoc} |
|
128
|
|
|
*/ |
|
129
|
|
|
public function count() |
|
130
|
|
|
{ |
|
131
|
|
|
return $this->find()->count(); |
|
132
|
|
|
} |
|
133
|
|
|
|
|
134
|
|
|
/** |
|
135
|
|
|
* @param DocumentSelector $selector |
|
136
|
|
|
*/ |
|
137
|
|
|
protected function setSelector(DocumentSelector $selector) |
|
138
|
|
|
{ |
|
139
|
|
|
$this->selector = $selector; |
|
140
|
|
|
} |
|
141
|
|
|
|
|
142
|
|
|
/** |
|
143
|
|
|
* @return DocumentSelector |
|
144
|
|
|
*/ |
|
145
|
|
|
final protected function selector() |
|
146
|
|
|
{ |
|
147
|
|
|
//Has to be cloned every time to prevent query collisions |
|
148
|
|
|
return clone $this->selector; |
|
149
|
|
|
} |
|
150
|
|
|
} |
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.