1: <?php
2:
3: namespace vierbergenlars\Forage\SearchIndex;
4:
5: use vierbergenlars\Forage\Transport\TransportInterface;
6:
7: /**
8: * The search index
9: */
10: class Index
11: {
12: /**
13: * The documents in the queue to be uploaded
14: * @var array
15: */
16: protected $uploadedDocuments = array();
17:
18: /**
19: * The documents in the queue to be deleted
20: * @var array
21: */
22: protected $removedDocuments = array();
23:
24: /**
25: * The fields to facet the uploaded documents on
26: * @var array
27: */
28: protected $facetFields = array();
29:
30: /**
31: * The transport to use
32: * @var \vierbergenlars\Forage\Transport\TransportInterface
33: */
34: protected $transport;
35:
36: /**
37: * Creates a new search index
38: * @param \vierbergenlars\Forage\Transport\TransportInterface $transport
39: * @param array $documents The documents to upload. The array key is the document ID.
40: * @param array $facetFields The fields to facet on
41: */
42: public function __construct(TransportInterface $transport, array $documents = array(), array $facetFields = array())
43: {
44: foreach($documents as $id=>$document)
45: $this->addDocument($id, $document);
46: foreach($facetFields as $field)
47: $this->addFacetField ($field);
48: $this->transport = $transport;
49: }
50:
51: /**
52: * Adds a field to facet on
53: * @param string $field
54: * @return \vierbergenlars\Forage\SearchIndex\Index
55: */
56: public function addFacetField($field)
57: {
58: $this->facetFields[$field] = true;
59: return $this;
60: }
61:
62: /**
63: * Removes a field that was faceted on
64: * @param string $field
65: * @return \vierbergenlars\Forage\SearchIndex\Index
66: */
67: public function removeFacetField($field)
68: {
69: unset($this->facetFields[$field]);
70: return $this;
71: }
72:
73: /**
74: * Adds a new document to the index
75: * @param string|int $id The id of the document
76: * @param array $document The data for the document
77: * @return \vierbergenlars\Forage\SearchIndex\Index
78: */
79: public function addDocument($id, $document)
80: {
81: if (!is_array($document))
82: throw new \BadMethodCallException('Parameter 1 of ' . __METHOD__ . ' should be array, ' . (is_object($document) ? get_class($document) : gettype($document)) . ' given.');
83: unset($this->removedDocuments[$id]);
84: $this->uploadedDocuments[$id] = $document;
85: return $this;
86: }
87:
88: /**
89: * Removes a document from the index
90: * @param int|string $id The id of the document
91: * @return \vierbergenlars\Forage\SearchIndex\Index
92: */
93: public function removeDocument($id)
94: {
95: if(isset($this->uploadedDocuments[$id]))
96: unset($this->uploadedDocuments[$id]);
97: $this->removedDocuments[$id] = true;
98: return $this;
99: }
100:
101: /**
102: * Sends all changes to the index to the transport
103: * @return bool
104: */
105: public function flush()
106: {
107: $statuses = array();
108: foreach($this->removedDocuments as $id=>$_)
109: {
110: $statuses[] = $this->transport->deleteDoc($id);
111: }
112: if(count($this->uploadedDocuments) > 0)
113: $statuses[] = $this->transport->indexBatch($this->uploadedDocuments, array_keys($this->facetFields));
114:
115: $this->removedDocuments = array();
116: $this->uploadedDocuments = array();
117:
118: return !in_array(false, $statuses);
119: }
120: }
121: