2 namespace App\Model\Table;
6 use Cake\ORM\RulesChecker;
8 use Cake\Validation\Validator;
13 * @method \App\Model\Entity\Category get($primaryKey, $options = [])
14 * @method \App\Model\Entity\Category newEntity($data = null, array $options = [])
15 * @method \App\Model\Entity\Category[] newEntities(array $data, array $options = [])
16 * @method \App\Model\Entity\Category|bool save(\Cake\Datasource\EntityInterface $entity, $options = [])
17 * @method \App\Model\Entity\Category patchEntity(\Cake\Datasource\EntityInterface $entity, array $data, array $options = [])
18 * @method \App\Model\Entity\Category[] patchEntities($entities, array $data, array $options = [])
19 * @method \App\Model\Entity\Category findOrCreate($search, callable $callback = null, $options = [])
21 * @mixin \Cake\ORM\Behavior\TimestampBehavior
23 class CategoriesTable extends Table
29 * @param array $config The configuration for the Table.
32 public function initialize(array $config)
34 parent::initialize($config);
36 $this->setTable('categories');
37 $this->setDisplayField('name');
38 $this->setPrimaryKey('id');
40 $this->addBehavior('Timestamp');
42 $this->belongsToMany('Locations',
44 'targetForeignKey' => 'location_id',
45 'foreignKey' => 'category_id',
46 'joinTable' => 'categories_locations',
47 'through' => 'CategoriesLocations',
53 * Default validation rules.
55 * @param \Cake\Validation\Validator $validator Validator instance.
56 * @return \Cake\Validation\Validator
58 public function validationDefault(Validator $validator)
62 ->allowEmpty('id', 'create');
65 ->requirePresence('name', 'create')
67 ->add('name', 'unique', ['rule' => 'validateUnique', 'provider' => 'table']);
71 ->allowEmpty('parent');
77 * Returns a rules checker object that will be used for validating
78 * application integrity.
80 * @param \Cake\ORM\RulesChecker $rules The rules object to be modified.
81 * @return \Cake\ORM\RulesChecker
83 public function buildRules(RulesChecker $rules)
85 $rules->add($rules->isUnique(['name']));
91 * returns a query that will find all the categories as a list.
93 public function getAllCategories() {
94 // find the full list of categories to show the user.
95 $categoriesList = $this->find ( 'list', [
97 'valueField' => 'name',
102 return $categoriesList;
106 * returns a query that will locate all of the locations in the specified category with 'id'.
108 public function getLocationsInCategory($id)
110 // query all the locations belonging to this category.
111 $locationsInCategory = $this->CategoriesLocations->find('all', [
112 'conditions' => [ 'category_id' => $id ],
113 'contain' => ['Locations']
115 return $locationsInCategory;
119 * returns a query that finds all locations in the category that fit within the southwest and northeast
122 public function getLocationsInCategoryInBox($id, $sw_lat, $sw_long, $ne_lat, $ne_long, $start = null, $end = null)
124 // query all the locations belonging to this category.
125 $locationsInCategory = $this->CategoriesLocations->find('all', [
126 'conditions' => [ 'category_id' => $id ],
127 'contain' => ['Locations', 'Categories']
130 Log::Debug('bounds=' . $sw_lat . ', '. $sw_long . ' to ' . $ne_lat . ', ' . $ne_long);
132 $bounds = [ $sw_lat , $sw_long , $ne_lat , $ne_long ];
135 Log::Debug("failed to calculate the bounding box!");
137 Log::Debug("bounding box: " . var_export($bounds, true));
140 // use the boundaries to restrict the lookup.
141 // order: min_lat, min_long, max_lat, max_long.
142 $locationsInCategory = $locationsInCategory->where (
143 function ($exp) use ($bounds) {
144 return $exp->gte ( 'lat', $bounds [0] )->gte ( 'lng', $bounds [1] )->lte ( 'lat', $bounds [2] )->lte ( 'lng', $bounds [3] );
148 if (($start !== null) && ($end !== null)) {
149 Log::debug('start of range = ' . $start . ' and end = ' . $end);
150 $locationsInCategory= $locationsInCategory->order(['lat desc', 'lng desc']);
151 $chunk = $end - $start + 1;
152 $locationsInCategory= $locationsInCategory->limit($chunk);
153 $page = 1 + (int)($start / $chunk);
154 $locationsInCategory= $locationsInCategory->page($page);
155 Log::debug('page = ' . $page . ' and chunk = ' . $chunk);
158 return $locationsInCategory;
161 public function getChewedLocationsInCategoryInBox($id, $sw_lat, $sw_long, $ne_lat, $ne_long, $start = null, $end = null)
163 $locationsInCategory = $this->getLocationsInCategoryInBox($id, $sw_lat, $sw_long, $ne_lat, $ne_long, $start, $end);
165 $locationsToSerialize = [];
167 // make an array with the useful parts of the location data.
168 foreach ($locationsInCategory as $location) {
169 $lat_and_long = $location->location->lat. ',' . $location->location->lng;
170 if (array_key_exists ( $lat_and_long, $locationsToSerialize)) {
171 continue; // already got it.
174 //Log::debug('got an icon value of: ' . $location->category->image);
176 // we don't include lat and lng below since they are encoded as array key.
177 $locationsToSerialize[$lat_and_long] = ['name' => $location->location->name,
178 'loc' => $location->location->location,
179 'icon' => $location->category->image,
180 'id' => $location->location_id,
184 return $locationsToSerialize;