Overview

Namespaces

  • Mapbender
    • Component
      • HTTP
    • CoreBundle
      • Command
      • Component
        • Exception
      • Controller
      • DataFixtures
        • ORM
      • DependencyInjection
      • Element
        • Type
      • Entity
      • EventListener
      • Extension
      • Form
        • DataTransformer
        • EventListener
        • Type
      • Security
      • Template
    • KmlBundle
      • Element
    • ManagerBundle
      • Controller
      • Form
        • DataTransformer
        • Type
    • MonitoringBundle
      • Command
      • Component
      • Controller
      • DependencyInjection
      • Entity
      • EventListener
      • Form
    • PrintBundle
      • Component
      • Controller
    • WmcBundle
      • Component
        • Exception
      • Element
        • Type
      • Entity
      • Form
        • Type
    • WmsBundle
      • Component
        • Exception
      • Controller
      • DependencyInjection
      • Element
        • Type
      • Entity
      • Event
      • Form
        • EventListener
        • Type
    • WmtsBundle
      • Component
        • Exception
      • Controller
      • Entity
      • Form
        • Type
  • None
  • PHP

Classes

  • Application
  • ApplicationYAMLMapper
  • BoundingBox
  • Element
  • InstanceConfiguration
  • InstanceConfigurationOptions
  • MapbenderBundle
  • ProxyService
  • SQLSearchEngine
  • StateHandler
  • Template
  • Utils

Interfaces

  • InstanceLayerIn
  • SearchEngine
  • Overview
  • Namespace
  • Class
  • Tree
  • Deprecated
  • Todo
  • Download
  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:      * SQL Autocomplete method
 17:      *
 18:      * @todo Make like search configurable (exact, left, right, both)
 19:      * @todo Make case invariant configurable
 20:      * @todo Limit results
 21:      *
 22:      * @param  Array  $config     Search configuration
 23:      * @param  String $key        Autocomplete field nme
 24:      * @param  String $value      Autocomplete value
 25:      * @param  Object $properties All form values
 26:      * @param  String $srs        Current map SRS
 27:      * @param  Array  $extent     Current map extent
 28:      * @return Array              Autocomplete suggestions
 29:      */
 30:     public function autocomplete($config, $key, $value, $properties, $srs, $extent)
 31:     {
 32:         // First, get DBAL connection service, either given one or default one
 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:         // Build SELECT
 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:         // Add FROM
 57:         $qb->from($config['class_options']['relation'], 't');
 58: 
 59:         // Build WHERE condition
 60:         $cond = $qb->expr()->andx();
 61:         $params = array();
 62:         for($i = 0; $i < count($keys); $i++)
 63:         {
 64:             // @todo: Platform independency (::varchar, lower)
 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:         // Create prepared statement and execute
 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:      * Actual SQL search method
101:      *
102:      * @todo Make like search configurable (exact, left, right, both)
103:      * @todo Make case invariant configurable
104:      * @todo Paging
105:      *
106:      * @param  Array $config Search configuration
107:      * @param  Array $data   Form data
108:      * @param  String $srs   Search extent SRS
109:      * @param  Array $extent Search extent
110:      * @return Array         Search results
111:      */
112:     public function search($config, $data, $srs, $extent)
113:     {
114:         // First, get DBAL connection service, either given one or default one
115:         $connection = $config['class_options']['connection'] ? : 'default';
116:         $connection = $this->container->get('doctrine.dbal.' . $connection . '_connection');
117:         $qb = $connection->createQueryBuilder();
118: 
119:         // Build SELECT
120:         $select = implode(', ', array_map(function($attribute)
121:                         {
122:                             return 't.' . $attribute;
123:                         }, $config['class_options']['attributes']));
124:         // Add geometry to SELECT
125:         // // @todo: Platform independency (ST_AsGeoJSON)
126:         $select .= ', ST_AsGeoJSON(' . $config['class_options']['geometry_attribute'] . ') as geom';
127: 
128:         $qb->select($select);
129:         // Add FROM
130:         $qb->from($config['class_options']['relation'], 't');
131: 
132:         // Build WHERE condition
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:                 // Autocomplete value given, match to configured attribute
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:                 // Split
145:                 $keys = $config['form'][$key]['split'];
146:                 $values = explode(' ', $value);
147:                 for($i = 0; $i < count($keys); $i++)
148:                 {
149:                     // @todo: Platform independency (::varchar, lower)
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:         // Create prepared statement and execute
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:         // Rewrite rows as GeoJSON features
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: 
Mapbender3 API documenation API documentation generated by ApiGen 2.8.0