1: <?php
2:
3: namespace Mapbender\CoreBundle\Component;
4:
5: class SQLSearchEngine
6: {
7:
8: protected $container;
9:
10: public function __construct($container)
11: {
12: $this->container = $container;
13: }
14:
15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29:
30: public function autocomplete($config, $key, $value, $properties, $srs, $extent)
31: {
32:
33: $connection = $config['class_options']['connection'] ? : 'default';
34: $connection = $this->container->get('doctrine.dbal.' . $connection . '_connection');
35: $qb = $connection->createQueryBuilder();
36:
37: $keys = array($key);
38: $values = array($value);
39: if(array_key_exists('split', $config['form'][$key]))
40: {
41: $keys = $config['form'][$key]['split'];
42: $values = explode(' ', $value);
43: }
44:
45:
46: $select = implode(', ', array_map(function($attribute)
47: {
48: return 't.' . $attribute;
49: }, $keys));
50: if(array_key_exists('autocomplete-key', $config['form'][$key]))
51: {
52: $select .= ', t.' . $config['form'][$key]['autocomplete-key'];
53: }
54: $qb->select($select);
55:
56:
57: $qb->from($config['class_options']['relation'], 't');
58:
59:
60: $cond = $qb->expr()->andx();
61: $params = array();
62: for($i = 0; $i < count($keys); $i++)
63: {
64:
65: $cond->add($qb->expr()->like('LOWER(t.' . $keys[$i] . '::varchar)', '?'));
66: $params[] = '%' . (count($values) > $i ? strtolower($values[$i]) : '') . '%';
67: }
68: $qb->where($cond);
69:
70:
71: $this->container->get('logger')->info('SQL: ' . $qb->getSql() . '; Params: ' . print_r($params, true));
72: $stmt = $connection->executeQuery($qb->getSql(), $params);
73: $rows = $stmt->fetchAll(\PDO::FETCH_ASSOC);
74:
75: array_walk($rows, function(&$row) use ($key, $keys, $config)
76: {
77: $value = array();
78: foreach($keys as $k)
79: {
80: $value[] = $row[$k];
81: }
82:
83: if(array_key_exists('autocomplete-key', $config['form'][$key]))
84: {
85: $row = array(
86: 'key' => $row[$config['form'][$key]['autocomplete-key']],
87: 'value' => implode(' ', $value));
88: } else
89: {
90: $row = array(
91: 'value' => implode(' ', $value)
92: );
93: }
94: });
95:
96: return $rows;
97: }
98:
99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111:
112: public function search($config, $data, $srs, $extent)
113: {
114:
115: $connection = $config['class_options']['connection'] ? : 'default';
116: $connection = $this->container->get('doctrine.dbal.' . $connection . '_connection');
117: $qb = $connection->createQueryBuilder();
118:
119:
120: $select = implode(', ', array_map(function($attribute)
121: {
122: return 't.' . $attribute;
123: }, $config['class_options']['attributes']));
124:
125:
126: $select .= ', ST_AsGeoJSON(' . $config['class_options']['geometry_attribute'] . ') as geom';
127:
128: $qb->select($select);
129:
130: $qb->from($config['class_options']['relation'], 't');
131:
132:
133: $cond = $qb->expr()->andx();
134: $params = array();
135: foreach($data['form'] as $key => $value)
136: {
137: if(array_key_exists($key, $data['autocomplete_keys']))
138: {
139:
140: $cond->add($qb->expr()->eq(
141: 't.' . $config['form'][$key]['autocomplete-key'], $data['autocomplete_keys'][$key]));
142: } else if(array_key_exists('split', $config['form'][$key]))
143: {
144:
145: $keys = $config['form'][$key]['split'];
146: $values = explode(' ', $value);
147: for($i = 0; $i < count($keys); $i++)
148: {
149:
150: $cond->add($qb->expr()->like('LOWER(t.' . $keys[$i] . '::varchar)', '?'));
151: $params[] = '%' . (count($values) > $i ? strtolower($values[$i]) : '') . '%';
152: }
153: } else
154: {
155: $cond->add($qb->expr()->like('t.' . $key, '?'));
156: $params[] = '%' . $value . '%';
157: }
158: }
159: $qb->where($cond);
160:
161:
162: $this->container->get('logger')->info('SQL: ' . $qb->getSql() . '; Params: ' . print_r($params, true));
163: $stmt = $connection->executeQuery($qb->getSql(), $params);
164: $rows = $stmt->fetchAll();
165:
166:
167: array_walk($rows, function(&$row)
168: {
169: $feature = array(
170: 'type' => 'Feature',
171: 'properties' => $row,
172: 'geometry' => json_decode($row['geom'])
173: );
174: unset($feature['properties']['geom']);
175: $row = $feature;
176: });
177:
178: return $rows;
179: }
180:
181: }
182: