1
+ <?php
2
+ /**
3
+ * Copyright (c)2014-2014 heiglandreas
4
+ *
5
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ * of this software and associated documentation files (the "Software"), to deal
7
+ * in the Software without restriction, including without limitation the rights
8
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ * copies of the Software, and to permit persons to whom the Software is
10
+ * furnished to do so, subject to the following conditions:
11
+ *
12
+ * The above copyright notice and this permission notice shall be included in
13
+ * all copies or substantial portions of the Software.
14
+ *
15
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ * LIBILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ * THE SOFTWARE.
22
+ *
23
+ * @category
24
+ * @author Andreas Heigl<[email protected] >
25
+ * @copyright ©2014-2014 Andreas Heigl
26
+ * @license http://www.opesource.org/licenses/mit-license.php MIT-License
27
+ * @version 0.0
28
+ * @since 04.02.14
29
+ * @link https://github.com/heiglandreas/
30
+ */
31
+
32
+ namespace Phpug \Api \v1 ;
33
+
34
+ use Phpug \ORM \Query \AST \Functions \DistanceFrom ;
35
+ use Zend \Mvc \Controller \AbstractActionController ;
36
+ use Sabre \VObject ;
37
+ use Zend \Json \Json ;
38
+
39
+ class LocationController extends AbstractActionController
40
+ {
41
+ private $ acceptCriteria = array (
42
+ 'Zend\View\Model\JsonModel ' => array (
43
+ 'application/json ' ,
44
+ 'text/html ' ,
45
+ ),
46
+ 'Zend\View\Model\FeedModel ' => array ('application/rss+xml ' ),
47
+ );
48
+
49
+ /**
50
+ * Get a list of groups that are nearest to the given coordinates.
51
+ *
52
+ * Coordinates are given via the parameters <var>lat</var and <var>lon</var>,
53
+ * the maximum distance from the current location is given via <var>distance</var>
54
+ * and the maximum number of entries is given via the parameter <var>max</var>
55
+ *
56
+ * This method will then return the maximum number of entries within the given
57
+ * range. If less than the maximum number of entries is found within the distance
58
+ * only that number of entries will be returned. When no distance is given or the
59
+ * distance is given as "0" the maximum number of entries will be retrieved.
60
+ *
61
+ * @return mixed|\Zend\View\Model\ModelInterface
62
+ * @throws \UnexpectedValueException
63
+ */
64
+ public function nextGroupsAction ()
65
+ {
66
+ $ adapter = $ this ->getAdapter ();
67
+ $ response = $ this ->getResponse ();
68
+ $ viewModel = $ this ->getViewModel ();
69
+
70
+ Json::$ useBuiltinEncoderDecoder = true ;
71
+
72
+ // Get Latitude, Longitude, distance and/or number of groups to retrieve
73
+ $ latitude = $ this ->params ()->fromQuery ('latitude ' );
74
+ $ longitude = $ this ->params ()->fromQuery ('longitude ' );
75
+ $ distance = $ this ->params ()->fromQuery ('distance ' , null );
76
+ $ number = $ this ->params ()->fromQuery ('count ' , null );
77
+
78
+
79
+ //$this->sorter = $this->getServiceManager('Phpug\Sorter\Usergroup\Distance');
80
+ $ groups = $ this ->findGroupsWithinRangeAndDistance ($ latitude , $ longitude , $ distance , $ number );
81
+ $ return = array (
82
+ 'currentLocation ' => array (
83
+ 'latitude ' => $ latitude ,
84
+ 'longitude ' => $ longitude ,
85
+ ),
86
+ 'groups ' => array (),
87
+ );
88
+ // $hydrator = $this->getServiceManager('Phpug\Hydrator\Usergroup');
89
+ foreach ($ groups as $ group ) {
90
+ $ grp = array (
91
+ 'name ' => $ group [0 ]->getName (),
92
+ 'latitude ' => $ group [0 ]->getLatitude (),
93
+ 'longitude ' => $ group [0 ]->getLongitude (),
94
+ 'shortname ' => $ group [0 ]->getShortname (),
95
+ 'distance ' => $ group ['distance ' ],
96
+ 'icalendar_url ' => $ group [0 ]->getIcalendar_url (),
97
+ 'url ' => $ group [0 ]->getUrl (),
98
+ 'contacts ' => array (),
99
+ 'uri ' => '' ,
100
+ );
101
+
102
+ foreach ($ group [0 ]->getContacts () as $ contact ) {
103
+ $ grp ['contacts ' ][] = array (
104
+ 'service ' => $ contact ->getServiceName (),
105
+ 'name ' => $ contact ->getName (),
106
+ 'uri ' => $ contact ->getUrl (),
107
+ );
108
+ }
109
+
110
+ $ return ['groups ' ][] = $ grp ;
111
+ }
112
+ $ viewModel ->setVariable ('groups ' , $ return );
113
+
114
+ return $ viewModel ;
115
+ }
116
+
117
+ protected function getAdapter ()
118
+ {
119
+ $ format = $ this ->params ()->fromQuery ('format ' , null );
120
+ switch ($ format ) {
121
+ case 'sphp ' :
122
+ $ contentType = 'text/plain ' ;
123
+ $ adapter = '\Zend\Serializer\Adapter\PhpSerialize ' ;
124
+ break ;
125
+ case 'json ' :
126
+ default :
127
+ $ contentType = 'application/json ' ;
128
+ $ adapter = '\Zend\Serializer\Adapter\Json ' ;
129
+ break ;
130
+ }
131
+ $ this ->getResponse ()->getHeaders ()->addHeaderLine ('Content-Type ' , $ contentType );
132
+
133
+ return new $ adapter ;
134
+ }
135
+
136
+ protected function getViewModel ()
137
+ {
138
+ return $ this ->acceptableViewModelSelector ($ this ->acceptCriteria );
139
+ }
140
+
141
+ protected function findGroupsWithinRangeAndDistance ($ lat , $ lon , $ distance = null , $ number = null )
142
+ {
143
+ /** @var \Doctrine\ORM\EntityManager $em */
144
+ $ em = $ this ->getServiceLocator ()->get ('doctrine.entitymanager.orm_default ' );
145
+ DistanceFrom::setLatitudeField ('latitude ' );
146
+ DistanceFrom::setLongitudeField ('longitude ' );
147
+ DistanceFrom::setRadius (6367 );
148
+ $ em ->getConfiguration ()->addCustomNumericFunction ('DISTANCEFROM ' , 'Phpug\ORM\Query\AST\Functions\DistanceFrom ' );
149
+
150
+ $ qs = 'SELECT p, DISTANCEFROM( ' . (float ) $ lat . ', ' . (float ) $ lon . ') AS distance FROM \Phpug\Entity\Usergroup p WHERE p.state = 1 ' ;
151
+
152
+
153
+ if ($ distance ) {
154
+ $ qs .= ' AND DISTANCEFROM( ' . (float ) $ lat . ', ' . (float ) $ lon . ') <= ' . (float ) $ distance ;
155
+ }
156
+
157
+ $ qs .= ' ORDER BY distance ' ;
158
+
159
+ $ query = $ em ->createQuery ($ qs );
160
+ if ($ number ) {
161
+ $ query ->setMaxResults ($ number );
162
+ }
163
+
164
+ return $ query ->getResult ();
165
+
166
+
167
+ }
168
+ }
0 commit comments