Enhance tca 39/27639/8
authorSebastian Fischer <typo3@evoweb.de>
Sat, 15 Feb 2014 17:31:16 +0000 (18:31 +0100)
committerSebastian Fischer <typo3@evoweb.de>
Fri, 28 Mar 2014 21:11:18 +0000 (22:11 +0100)
Enhance plugin flexform
Remove closing ?> Tags
Implement major parts of the update script
Implement basic search

Change-Id: If81a93aac20d7daf0de75d0fcc5b5247c0180d55
Reviewed-on: https://review.typo3.org/27639
Reviewed-by: Sebastian Fischer
Tested-by: Sebastian Fischer
49 files changed:
Classes/Controller/MapController.php
Classes/Domain/Model/Attribute.php
Classes/Domain/Model/Category.php [new file with mode: 0644]
Classes/Domain/Model/Constraint.php
Classes/Domain/Model/Location.php
Classes/Domain/Model/Zipcodearea.php [deleted file]
Classes/Domain/Repository/CategoryRepository.php [new file with mode: 0644]
Classes/Domain/Repository/CountryRepository.php [new file with mode: 0644]
Classes/Domain/Repository/LocationRepository.php
Classes/Domain/Repository/SessionRepository.php [new file with mode: 0644]
Classes/Domain/Repository/StaticCountryRepository.php [deleted file]
Classes/Hook/TceMainHook.php
Classes/Service/GeocodeService.php
Classes/Utility/ExtensionConfiguration.php [deleted file]
Classes/Utility/ExtensionConfigurationUtility.php [new file with mode: 0644]
Classes/Utility/UpdateUtility.php [new file with mode: 0644]
Classes/View/SelectTreeview.php [deleted file]
Classes/ViewHelpers/Form/SelectCountriesViewHelper.php [new file with mode: 0644]
Classes/ViewHelpers/Form/SelectStaticCountriesViewHelper.php [deleted file]
Classes/ViewHelpers/Format/BinaryAndViewHelper.php [new file with mode: 0644]
Classes/ViewHelpers/MinifyViewHelper.php
Classes/ViewHelpers/NoopViewHelper.php [deleted file]
Configuration/FlexForms/flexform_ds.xml
Configuration/PageTS/ModWizards.ts
Configuration/TCA/tx_storefinder_domain_model_attribute.php [new file with mode: 0644]
Configuration/TCA/tx_storefinder_domain_model_location.php [new file with mode: 0644]
Configuration/Tca/tx_storefinder_domain_model_attribute.php [deleted file]
Configuration/Tca/tx_storefinder_domain_model_location.php [deleted file]
Configuration/TypoScript/setup.txt
Documentation/license.txt [new file with mode: 0644]
Resources/Private/Language/locallang_be.xml
Resources/Private/Language/locallang_db.xml
Resources/Private/Partials/List.html
Resources/Private/Partials/Map.html
Resources/Private/Partials/Search.html
Resources/Private/Templates/Map/Map.html
Resources/Private/Templates/Map/Search.html [deleted file]
Resources/Private/Templates/Map/SearchWithListMap.html [deleted file]
Resources/Public/Icons/ce_wiz.gif [deleted file]
Resources/Public/Icons/google-maps-icon.png [new file with mode: 0644]
Resources/Public/JavaScript/InfoBubble.js
Resources/Public/JavaScript/map.js
Resources/Public/Stylesheet/layout.css
class.ext_update.php [new file with mode: 0644]
composer.json
ext_emconf.php
ext_localconf.php
ext_tables.php
ext_tables.sql

index 6e8933a..a6c7192 100644 (file)
@@ -23,487 +23,224 @@ namespace Evoweb\StoreFinder\Controller;
  * This copyright notice MUST APPEAR in all copies of the script!
  ***************************************************************/
 
+use Evoweb\StoreFinder\Domain\Model;
+use Evoweb\StoreFinder\Domain\Repository;
+
+/**
+ * Class MapController
+ *
+ * @package Evoweb\StoreFinder\Controller
+ */
 class MapController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController {
        /**
         * @var \Evoweb\StoreFinder\Domain\Repository\LocationRepository
+        * @inject
         */
-       protected $repository;
+       protected $locationRepository;
 
        /**
+        * @var \Evoweb\StoreFinder\Domain\Repository\CategoryRepository
+        * @inject
+        */
+       protected $categoryRepository;
+
+       /**
+        * @var \Evoweb\StoreFinder\Domain\Repository\SessionRepository
+        * @inject
+        */
+       protected $sessionRepository;
+
+       /**
+        * Initializes the controller before invoking an action method.
+        *
+        * Override this method to solve tasks which all actions have in
+        * common.
+        *
         * @return void
         */
        protected function initializeAction() {
-               $this->repository = $this->objectManager->get('Evoweb\StoreFinder\Domain\Repository\LocationRepository');
+               $this->settings['allowedCountries'] = explode(',', $this->settings['allowedCountries']);
+               $this->locationRepository->setSettings($this->settings);
        }
 
        /**
-        * @param \Evoweb\StoreFinder\Domain\Model\Constraint $search
+        * Action responsible for rendering search, map and list partial
+        *
+        * @param Model\Constraint $search
         * @return void
         */
-       public function searchWithListMapAction(\Evoweb\StoreFinder\Domain\Model\Constraint $search = NULL) {
+       public function mapAction(Model\Constraint $search = NULL) {
+               $afterSearch = 0;
                if ($search !== NULL) {
-                       $locations = $this->repository->findAll();
+                       $search = $this->geocodeAddress($search);
+                       $locations = $this->locationRepository->findByConstraint($search);
+
+                       $center = $this->getCenter($search);
+                       $center = $this->setZoomLevel($center, $search);
+
+                       $afterSearch = 1;
 
-                       $this->view->assign('showResults', TRUE);
-                       $this->view->assign('center', $this->getCenter($search));
-                       $this->view->assign('numberOfLocations', $locations->count());
+                       $this->view->assign('center', $center);
+                       $this->view->assign('numberOfLocations', is_object($locations) ? count($locations) : $locations->count());
                        $this->view->assign('locations', $locations);
+               } elseif ($this->settings['singleLocationId']) {
+                       $location = $this->locationRepository->findByUid($this->settings['singleLocationId']);
+
+                       $search = $this->objectManager->get('Evoweb\\StoreFinder\\Domain\\Model\\Constraint');
+
+                       $this->view->assign('numberOfLocations', is_object($location) ? 1 : 0);
+                       $this->view->assign('locations', array($location));
+               } else {
+                       $search = $this->objectManager->get('Evoweb\\StoreFinder\\Domain\\Model\\Constraint');
                }
+
+               $this->addCategoryFilterToView();
+               $this->view->assign('afterSearch', $afterSearch);
+               $this->view->assign('search', $search);
+               $this->view->assign('static_info_tables', \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded('static_info_tables') ? 1 : 0);
        }
 
        /**
-        * @return string
+        * Add categories give in settings to view
+        *
+        * @return void
         */
-       protected function searchAction() {
+       protected function addCategoryFilterToView() {
+               if ($this->settings['categories']) {
+                       $categories = $this->categoryRepository->findByUids($this->settings['categories']);
+
+                       $this->view->assign('categories', $categories);
+               }
        }
 
        /**
-        * @return void
+        * Get center from query result based on center of all coordinates. If only one
+        * is found this is used. In case none was found the center based on the request
+        * gets calculated
+        *
+        * @param \TYPO3\CMS\Extbase\Persistence\QueryResultInterface $queryResult
+        * @return Model\Location
         */
-       protected function mapAction() {
-               $center = $this->getCenter();
-               $locations = $this->repository->findAll();
+       protected function getCenterOfQueryResult($queryResult) {
+               if ($queryResult->count() == 1) {
+                       return $queryResult->getFirst();
+               } elseif (!$queryResult->count()) {
+                       return $this->getCenter();
+               }
 
-               $this->view->assign('numberOfLocations', $locations->count());
-               $this->view->assign('center', $center);
-               $this->view->assign('locations', $locations);
+               /** @var Model\Location $center */
+               $center = $this->objectManager->get('Evoweb\StoreFinder\Domain\Model\Location');
+
+               $x = $y = $z = 0;
+               /** @var Model\Location $location */
+               foreach ($queryResult as $location) {
+                       $x += cos($location->getLatitude()) * cos($location->getLongitude());
+                       $y += cos($location->getLatitude()) * sin($location->getLongitude());
+                       $z += sin($location->getLatitude());
+               }
+
+               $x /= $queryResult->count();
+               $y /= $queryResult->count();
+               $z /= $queryResult->count();
+
+               $center->setLongitude(atan2($y, $x));
+               $center->setLatitude(atan2($z, sqrt($x * $x + $y * $y)));
+
+               return $center;
        }
 
        /**
-        * @param \Evoweb\StoreFinder\Domain\Model\Constraint $constraint
-        * @return \Evoweb\StoreFinder\Domain\Model\Location
+        * Geocode requested address and use as center or fetch location that was
+        * flagged as center. If
+        *
+        * @param Model\Constraint $constraint
+        * @return Model\Location
         */
-       protected function getCenter(\Evoweb\StoreFinder\Domain\Model\Constraint $constraint = NULL) {
+       protected function getCenter(Model\Constraint $constraint = NULL) {
                $center = NULL;
 
                if ($constraint !== NULL) {
                        if ($constraint->getLatitude() && $constraint->getLongitude()) {
-                               /** @var \Evoweb\StoreFinder\Domain\Model\Location $center */
+                               /** @var Model\Location $center */
                                $center = $this->objectManager->get('Evoweb\StoreFinder\Domain\Model\Location');
                                $center->setLatitude($constraint->getLatitude());
                                $center->setLongitude($constraint->getLongitude());
                        } else {
-                               $center = $this->objectManager
-                                       ->get('Evoweb\StoreFinder\Service\GeocodeService', $this->settings)
-                                       ->geocodeAddress($constraint);
+                               $center = $this->geocodeAddress($constraint);
                        }
                }
 
                if ($center === NULL) {
-                       $center = $this->repository->findOneByUseAsCenter(1);
+                       $center = $this->locationRepository->findOneByCenter();
                }
 
                if ($center === NULL) {
-                       $this->repository->setSettings($this->settings);
-                       $center = $this->repository->findCenter();
+                       $center = $this->locationRepository->findCenterByLatitudeAndLongitude();
                }
 
                return $center;
        }
 
-       private function _searchStore() {
-               $this->cObj = t3lib_div :: makeInstance("tslib_cObj");
-               $this->template = $this->cObj->fileResource($this->conf["templateFile"]);
-               $start = array ();
-               $this->_GP['start'] = array ();
-               if ($this->_GP['lat']) {
-                       $center_lat_lon->lat = (float) $this->_GP['lat'];
-                       $center_lat_lon->lon = (float) $this->_GP['lon'];
-               } else
-                       $center_lat_lon = $this->geocodeAddress($this->_GP);
-
-               if (count($this->_GP['start']['city']) > 1) {
-                       // more than one city found for startingpoint
-                       // show city selection
-                       $subpart = $this->cObj->getSubpart($this->template, "###SEARCHCITY_HEADER###");
-                       $marksHeader['###MULTISTARTINGPOINTS###'] = $this->pi_getLL('multiStartingPoints');
-
-                       $final = $this->cObj->substituteMarkerArray($subpart, $marksHeader);
-
-                       $subpart = $this->cObj->getSubpart($this->template, "###SEARCHCITY_DATA###");
-                       $lon = (float) $this->_GP['start']['lon'];
-                       $lat = (float) $this->_GP['start']['lat'];
-                       $i = 0;
-
-                       while (list ($key, $v) = each($this->_GP['start']['city'])) {
-                               //$marks['###FORMHEADER###'] = $this->pi_getLL('formHeader');
-                               $marks['###FORMSTART###'] = '<form method="post" action="' . $this->pi_getPageLink($GLOBALS['TSFE']->id) . '">';
-                               $marks['###CITYV###'] = ($GLOBALS['TSFE']->localeCharset == 'utf-8') ? htmlspecialchars(utf8_encode($key)) : htmlspecialchars($key);
-                               $marks['###RADIUSV###'] = (int) $this->_GP['radius'];
-                               $marks['###COUNTRYV###'] = $this->_GP['country'];
-                               $marks['###LATV###'] = (float) $lat[$i];
-                               $marks['###LONV###'] = (float) $lon[$i];
-                               $marks['###STORESEARCH###'] = $this->pi_getLL('storeSearch');
-                               $i++;
-                               $final .= $this->cObj->substituteMarkerArray($subpart, $marks);
+       /**
+        * Geocode address and retries if first attempt or value in session
+        * is not geocoded
+        *
+        * @param Model\Constraint $address
+        * @param bool $forceGeocoding
+        * @return Model\Constraint
+        */
+       protected function geocodeAddress($address, $forceGeocoding = FALSE) {
+               $hash = md5(serialize($address));
 
-                       }
-                       $final .= $this->cObj->getSubpart($this->template, "###SEARCHCITY_FOOTER###");
-                       return $final;
+               if (!($geocodedAddress = $this->sessionRepository->getCoordinateByHash($hash)) || $forceGeocoding) {
+                       $geocodedAddress = $this->objectManager
+                               ->get('Evoweb\\StoreFinder\\Service\\GeocodeService', $this->settings)
+                               ->geocodeAddress($address);
+                       $this->sessionRepository->addCoordinateForHash($geocodedAddress, $hash);
                }
 
-               $HTTP_POST_VARS['lat_lon'] = $center_lat_lon;
-               $this->_GP['lat_lon'] = $center_lat_lon;
-               /*
-                * get the stores
-                */
-               $mysqlResults = $this->_inradius($this->_GP, (int) $this->_GP['radius']);
-               if ($mysqlResults == NULL) {
-                       return '<div class="searchResultHeader">' . $this->pi_getLL('noStoresFound') . '</div>';
+                       // In case the address without geocoded location was stored in
+                       // session or the geocoding did not work a second try is done
+               if (!$geocodedAddress->isGeocoded() && !$forceGeocoding) {
+                       $geocodedAddress = $this->geocodeAddress($geocodedAddress, TRUE);
                }
-               $data['mysql'] = $mysqlResults;
-               $data['center'] = $center_lat_lon;
 
-               return $data;
+               return $geocodedAddress;
        }
 
-       private function _inradius($complete_address, $radius) {
-               global $TYPO3_CONF_VARS;
-               $_EXTCONF = unserialize($TYPO3_CONF_VARS['EXT']['extConf']['locator']);
-
-               if ($radius == 0)
-                       $radius = 1; // needed if 2 stores are nearly on same location
-               if ($this->conf['distanceUnit'] == 'miles')
-                       $radius = $radius * 1.6;
-
-               //If there are any limitations on the results set, get them here.
-               $results_limit = $this->conf['resultLimit'];
-
-               if ($results_limit > 0) {
-                       $results_limit = "0,$results_limit";
-               }
-
-               //debug($complete_address,'complete');
-               //Check to see if we already have starting lat/lon so we dont do double geocoding
-               // attention: $complete_address['lat_lon'] is of type stdClass
-               if (!$complete_address['lat_lon']->lat && !$complete_address['lat_lon']->lon) {
-                       $lat_lon = $this->geocodeAddress($complete_address);
-               } else {
-                       $lat_lon = $complete_address['lat_lon'];
-               }
-               $lat = (float) trim($lat_lon->lat);
-               $lon = (float) trim($lat_lon->lon);
-
-               if ($lat == '')
-                       return; // no coordinates found
-
-               // when categories are set by Typoscript use them
-               if ($this->conf['categories']) {
-                       $complete_address['categories'] = $this->conf['categories'];
-               }
-
-//             if ($this->_GP['category'])
-//                 $categories = $this->_GP['category'];
-
-
-               //Add in categories to the search criteria
-               //If they are not an array, make them an array.
-               $categories = $complete_address['categories'];
-
-               if (!is_array($categories)) {
-                       $categories = explode(',', $categories);
-               }
-               // when calendar base is used change fieldname
-               if ($this->conf['useFeUserData'] == 2)
-                       $categoryField = 'tx_locator_categoryuid';
-               else
-                       if ($this->conf['useFeUserData'] == 3)
-                               $categoryField = 'category';
-                       else
-                               $categoryField = 'categoryuid';
-               // here we have to fetch all subcategories if category is a parent
-               // and we use locator_categories
-               if ($this->conf['useFeUserData'] == 0 || $this->conf['useFeUserData'] == 4 || $this->conf['useFeUserData'] == 3) {
-                       foreach ($categories as $cat) {
-                               $cat = (int) trim($cat);
-                               if ($cat >= 0)
-                                       $addCat = $this->getChildCategories($cat);
-                       }
-
-                       for ($i = 0; $i < count($addCat); $i++)
-                               $categories[] = $addCat[$i];
-                       if ($this->conf['useFeUserData'] == 0) {
-                               // get the correct categoryUid for the default language
-                               for ($i = 0; $i < count($categories); $i++) {
-                                       $categories[$i] = $this->getL10nParentCategory($categories[$i]);
-                               }
-                       }
-
-                       $products = explode(',', $this->_GP['products']);
-                       if (count($products)) {
-                               $products_search = ' AND ( (';
-                               for ($i = 0; $i < count($products); $i++) {
-                                       $products_search .= ($i != 0) ? ' OR ' : '';
-                                       $products_search .= 'products like "%' . trim(strtoupper($products[$i])) . '%"';
-                               }
-                               // search in categorynames too
-                               $products_search .= ' ) OR (';
-                               for ($i = 0; $i < count($products); $i++) {
-                                       $products_search .= ($i != 0) ? ' OR ' : '';
-
-                                       $products_search .= 'b.name like "%' . trim(strtoupper($products[$i])) . '%"';
-                               }
-                               $products_search .= '))';
-                       }
-               }
-
-               reset($categories);
-               if ($categories[0] == '')
-                       unset ($categories[0]);
-               //Loop through and add each category to the query.
-
-
-               $category_search = "AND (";
-               if (count($categories) == 1) {
-                       if (!$categories[0]) {
-                               array_shift($categories);
-                       }
-
-                       $cat = (int) $categories[0]; // [0] -> [1] 13.01.2012    [1] -> [0] 29.02.2012
-                       $category_search .= " " . $categoryField . " = '$cat' ";
-                       $category_search .= " OR " . $categoryField . " LIKE '$cat,%' ";
-                       $category_search .= " OR " . $categoryField . " LIKE '%,$cat,%' ";
-                       $category_search .= " OR " . $categoryField . " LIKE '%,$cat' ";
-               } else {
-                       foreach ($categories as $cat) {
-                               $cat = (int) trim($cat);
-                               if ($counter == 0) {
-                                       $category_search .= " " . $categoryField . " = '$cat' ";
-                                       $category_search .= " OR " . $categoryField . " = '' ";
-                                       $category_search .= " OR " . $categoryField . " LIKE '$cat,%' ";
-                                       $category_search .= " OR " . $categoryField . " LIKE '%,$cat,%' ";
-                                       $category_search .= " OR " . $categoryField . " LIKE '%,$cat' ";
-                               } else {
-                                       if ($cat != 0) {
-                                               //                    $category_search .= " OR categories LIKE '%$cat%' ";
-                                               $category_search .= " OR " . $categoryField . " = '$cat' ";
-                                               $category_search .= " OR " . $categoryField . " LIKE '$cat,%' ";
-                                               $category_search .= " OR " . $categoryField . " LIKE '%,$cat,%' ";
-                                               $category_search .= " OR " . $categoryField . " LIKE '%,$cat' ";
-                                       }
-                               }
-                               $counter++;
-                       }
-               }
-               $category_search .= ')';
-               //debug($category_search);
-               //debug($categories);
-
-               // for tt_address special categorysearch
-               if ($this->conf['useFeUserData'] == 4) {
-                       if ($categories[0] == '')
-                               array_shift($categories);
-                       for ($k = 0; $k < count($categories); $k++) {
-                               if ($k == 0)
-                                       $cats = (int) $categories[$k];
-                               else
-                                       $cats .= ',' . (int) $categories[$k];
-                       }
-                       $category_search = ' AND b.uid_local = a.uid AND b.uid_foreign in (' . $cats . ')';
-               }
-
-//             debug($category_search);
-               //if (sizeof($categories) == 1 && $categories[0] == '') {
-               // N. Badri 16.09.2011
-               if (sizeof($categories) == 0 && $categories[0] == '') {
-                       $category_search = '';
+       /**
+        * Set zoom level for map based on radius
+        *
+        * @param Model\Location|Model\Constraint $location
+        * @param Model\Constraint $constraint
+        * @return Model\Location
+        */
+       protected function setZoomLevel($location, Model\Constraint $constraint) {
+               $zoom = 13;
+               if ($constraint->getRadius() > 500 && $constraint->getRadius() <= 1000) {
+                       $zoom = 12;
                }
-
-               $pi = M_PI;
-               // calculating distance in km
-               if ($this->conf['useFeUserData'] == 1) {
-                       $table = 'fe_users';
-                       if (t3lib_extMgm :: isLoaded('sr_feuser_register', 0))
-                               $fields = "*, uid as storeuid, www as url, name as storename, comments as notes, telephone as phone, zip as zipcode, tx_locator_lat as lat, tx_locator_lon as lon,(((acos(sin(($lat*$pi/180)) * sin((tx_locator_lat*$pi/180)) + cos(($lat*$pi/180)) *  cos((tx_locator_lat*$pi/180)) * cos((($lon - tx_locator_lon)*$pi/180)))))*6370) as distance";
-                       else // no comments field
-                               $fields = "*, uid as storeuid, www as url, name as storename,  telephone as phone, zip as zipcode, tx_locator_lat as lat, tx_locator_lon as lon,(((acos(sin(($lat*$pi/180)) * sin((tx_locator_lat*$pi/180)) + cos(($lat*$pi/180)) *  cos((tx_locator_lat*$pi/180)) * cos((($lon - tx_locator_lon)*$pi/180)))))*6370) as distance";
-
-                       if ($this->conf['displayMode'] == 'countryCitySelector') // search the city too
-                               $where_clause = 'city=' . $GLOBALS['TYPO3_DB']->fullQuoteStr($this->_GP['city'], 'fe_users') . ' AND ';
-
-                       $where_clause .= " pid IN (" . $this->conf['pid_list'] . ") AND (" . $this->conf['feUserGroup'] . " in (usergroup) OR " .
-                       " usergroup like '%," . $this->conf['feUserGroup'] . "' OR " .
-                       " usergroup like '%," . $this->conf['feUserGroup'] . ",%')" .
-                       " AND deleted='0' AND disable='0' $category_search HAVING distance <= $radius";
+               if ($constraint->getRadius() <= 500) {
+                       $zoom = 10;
                }
-               if ($this->conf['useFeUserData'] == 0) {
-                       $table = 'tx_locator_locations a, tx_locator_categories b';
-                       $fields = " distinct a.*, a.uid as storeuid, imageurl as image, (((acos(sin(($lat*$pi/180)) * sin((lat*$pi/180)) + cos(($lat*$pi/180)) *  cos((lat*$pi/180)) * cos((($lon - lon)*$pi/180)))))*6370) as distance";
-                       $fields .= ", (select group_concat(c.name separator ', ') from tx_locator_categories c where (a.categoryuid = c.uid OR a.categoryuid like concat('%,',c.uid) OR a.categoryuid like concat(c.uid,',%') OR a.categoryuid like concat('%,', concat(c.uid,',%')))) as name";
-                       $fields .= ", (select group_concat(c.name, ':', c.icon separator ', ') from tx_locator_attributes c where (a.attributes = c.uid OR a.attributes like concat('%,',c.uid) OR a.attributes like concat(c.uid,',%') OR a.attributes like concat('%,', concat(c.uid,',%')))) as attributes";
-                       $where_clause = " a.pid IN (" . $this->conf['pid_list'] . ")";
-
-                       $where_clause .= str_replace('tx_locator_locations', 'a', $this->cObj->enableFields('tx_locator_locations'));
-
-                       if ($this->conf['limitResultsToCountry']) {
-                               $where_clause .= ' AND a.country = (select cn_short_en from static_countries where cn_iso_2 = "' . strtoupper($this->_GP['country']) . '")';
-                       }
-
-/*
-debug($this->conf['categories']);
-                       if ($this->conf['categories']) {
-                           $category_search = ' AND a.categoryuid in (' . $this->conf['categories'] . ')';;
-                       }
-*/
-                       if (count($products) > 0)
-                               $where_clause .= $products_search;
-                       if ($category_search != '')
-                               $where_clause .= " AND b.uid = a.categoryuid"; // this works even if there are multiple categories in categoryuid
-
-                       if ($this->conf['searchByName'])
-                               $where_clause .= ' AND storename like ' . $GLOBALS['TYPO3_DB']->fullQuoteStr('%' . $this->_GP['storename'] . '%', 'tx_locator_locations');
-
-                       $where_clause .= " AND a.deleted='0' AND a.hidden='0' $category_search HAVING distance <= $radius";
-
-                       if ($this->conf['singleView.']['showRelatedStores']) {
-                               $where_clause .= ' AND relatedto=""';
-                       }
-
-
-                       if ($this->conf['notepadId'] == $GLOBALS['TSFE']->id && $this->conf['enableNotepad'] && $_COOKIE['notepadStoreUids']) {
-                               if (preg_match('/^[0-9,]*$/', $_COOKIE['notepadStoreUids']) == 1)
-                                   $uidList = $_COOKIE['notepadStoreUids'];
-                               else $uidList = '';
-                           $where_clause .= ' AND a.uid in (' . $uidList . ')';
-                       }
+               if ($constraint->getRadius() <= 100) {
+                       $zoom = 8;
                }
-
-
-               if ($this->conf['useFeUserData'] == 2) {
-                       $table = $this->conf['externalLocationTable'];
-                       $fields = "*, tx_locator_categoryuid as categoryuid, link as url, name as storename, description as notes,  zip as zipcode, tx_locator_lat as lat, tx_locator_lon as lon,(((acos(sin(($lat*$pi/180)) * sin((tx_locator_lat*$pi/180)) + cos(($lat*$pi/180)) *  cos((tx_locator_lat*$pi/180)) * cos((($lon - tx_locator_lon)*$pi/180)))))*6370) as distance";
-                       $where_clause = " pid IN (" . $this->conf['pid_list'] . ") AND deleted='0' AND hidden='0' $category_search HAVING distance <= $radius";
+               if ($constraint->getRadius() <= 25) {
+                       $zoom = 6;
                }
-
-
-               if ($this->conf['useFeUserData'] == 3) {
-                       $category_search = ' AND uid in (select uid_local from tt_news_cat_mm where uid_foreign in (' . implode(',', $categories) . '))';
-                       if ($this->conf['categories'])
-                               $category_search = ' AND uid in (select uid_local from tt_news_cat_mm where uid_foreign in (' . implode(',', $categories) . '))';
-
-                       $_categories = t3lib_div::trimExplode(',', $this->conf['categories'], 1);
-                       $_cat1 = array();
-                       $this->children = array();
-                       for ($i = 0; $i < count($_categories); $i++) {
-                               $this->children[] .= $_categories[$i];
-                               if ($_categories[$i] > '') {
-                               $_cat1 = array_merge($_cat1, $this->getChildCategories($_categories[$i]));
-                               $_cat1 = array_unique($_cat1);
-                               }
-                       }
-
-            $this->conf['categories'] = $_cat1;
-                       if ($this->conf['categories'])
-                               $category_search = ' AND uid in (select uid_local from tt_news_cat_mm where uid_foreign in (' . implode(',', $_cat1) . '))';
-
-                       $table = 'tt_news a';
-                       $fields = "*, a.uid as storeuid, a.category as categoryuid, a.tx_locator_url as url, a.tx_locator_storename as storename, a.tx_locator_notes as notes," .
-                       " a.tx_locator_city as city, a.tx_locator_address as address, a.tx_locator_zipcode as zipcode," .
-                       " a.tx_locator_icon as icon, a.tx_locator_hours as hours, a.tx_locator_imageurl as image," .
-                       " a.tx_locator_phone as phone,  a.tx_locator_email as email, a.tx_locator_lat as lat, a.tx_locator_lon as lon,(((acos(sin(($lat*$pi/180)) * sin((tx_locator_lat*$pi/180)) + cos(($lat*$pi/180)) *  cos((tx_locator_lat*$pi/180)) * cos((($lon - tx_locator_lon)*$pi/180)))))*6370) as distance";
-                       $where_clause = " pid IN (" . $this->conf['pid_list'] . ") AND deleted='0' AND hidden='0' $category_search HAVING distance <= $radius";
-                       $where_clause .= " AND tx_locator_lat != 0 AND tx_locator_lon != 0";
-                       $where_clause .= " AND upper(title) like '%" . strtoupper($this->_GP['storename']) . "%'";
-                       $where_clause .= $whereCat;
+               if ($constraint->getRadius() < 5) {
+                       $zoom = 4;
                }
-
-               //martin start
-               if ($this->conf['useFeUserData'] == 4) {
-                       if (is_array($categories)) {
-                               for ($i = 0; $i < count($categories); $i++) {
-                                       if ($i == 0)
-                                               $cats = '(' . $categories[$i];
-                                       else
-                                               $cats .= ',' . $categories[$i];
-                               }
-                               $cats .= ')';
-                       }
-
-                       $table = 'tt_address a, tt_address_group_mm b';
-                       $fields = "distinct a.*, a.addressgroup as categoryuid, a.www as url, a.company as storename, a.description as notes," .
-                       " a.city, a.address, a.zip as zipcode," .
-                       " a.image,";
-
-
-                       if (!$this->conf['useApproximation'])
-                               $fields .= " a.phone,  a.email, a.tx_locator_lat as lat, a.tx_locator_lon as lon,(((acos(sin(($lat*$pi/180)) * sin((tx_locator_lat*$pi/180)) + cos(($lat*$pi/180)) *  cos((tx_locator_lat*$pi/180)) * cos((($lon - tx_locator_lon)*$pi/180)))))*6370) as distance";
-                       else {
-                               // approximation
-                               // dx = 71.5 * (lon1 - lon2); 71.5km per degree
-                               // dy = 111.3 * (lat1 - lat2)
-                               $fields .= " a.phone,  a.email, a.tx_locator_lat as lat, a.tx_locator_lon as lon, SQRT(POW($lon-tx_locator_lon,2) * 5112 + POW($lat-tx_locator_lat,2) * 12387) as distance";
-                       }
-                       //    if ($this->_GP['categories'] > '') {
-                       if ($this->conf['useTtaddressWithoutGroups']) {
-                               // may be it is a better way to create a temporary table
-                               // with a select with $lat < $latmax and $lat > $latmin etc
-                               // create temporary table ttaddresstemp as (select ...)
-                               // and then use the temporary table for distance
-                               $latmax = $lat + $radius / 111.3;
-                               $latmin = $lat - $radius / 111.3;
-                               $lonmax = $lon + $radius / 71.5;
-                               $lonmin = $lon - $radius / 71.5;
-                $GLOBALS['TYPO3_DB']->admin_query('DROP TABLE IF EXISTS ttaddresstemp');
-                               $query = "CREATE TEMPORARY TABLE ttaddresstemp AS (SELECT * from tt_address where (tx_locator_lat < $latmax and tx_locator_lat > $latmin and
-                                       tx_locator_lon < $lonmax AND tx_locator_lon > $lonmin))";
-
-                $GLOBALS['TYPO3_DB']->admin_query($query);
-
-                               $table = 'tt_address a';
-                               $table = 'ttaddresstemp a';
-                $category_search = '';
-                       }
-// here seems a bug with $category_search
-//$array = array ( 1 => $category_search);
-//t3lib_div::devLog('addressData', 'tx_locator', 3, $array);
-//$category_search = '';
-
-
-                       if (!$this->conf['useTtaddressWithoutGroups']) {
-                       $fields .= ",(select group_concat(d.title) from tt_address_group d where (
-                                           d.uid =  (select group_concat(c.uid_foreign) from tt_address_group_mm c where c.uid_local = a.uid)
-                                           or (select group_concat(c.uid_foreign) from tt_address_group_mm c where c.uid_local = a.uid) like concat('%,',d.uid)
-                                           or (select group_concat(c.uid_foreign) from tt_address_group_mm c where c.uid_local = a.uid) like concat('%,',d.uid,',%')
-                                           or (select group_concat(c.uid_foreign) from tt_address_group_mm c where c.uid_local = a.uid) like concat(d.uid,',%')
-                                           )) as category";
-                       }
-                       //    }
-
-                       $where_clause .= " a.pid IN (" . $this->conf['pid_list'] . ") AND a.deleted='0' AND a.hidden='0' $category_search HAVING distance <= $radius";
-//                     $where_clause .= " a.pid IN (" . $this->conf['pid_list'] . ") AND a.deleted='0' AND a.hidden='0' $category_search";
-
-//                     $where_clause .= " AND (((acos(sin(($lat*$pi/180)) * sin((tx_locator_lat*$pi/180)) + cos(($lat*$pi/180)) *  cos((tx_locator_lat*$pi/180)) * cos((($lon - tx_locator_lon)*$pi/180)))))*6370) <=  $radius";
-
-                       $where_clause .= " AND tx_locator_lat != 0 AND tx_locator_lon != 0";
+               if ($constraint->getRadius() < 3) {
+                       $zoom = 3;
                }
-               //martin stop
-
-               if ($this->_GP['mode'] == 'mapAllNoFormView' || $this->conf['displayMode'] == 'mapAllView') {
-                       if ($this->conf['showAreas'])
-                               $orderBy = "lat desc";
-                       else
-                               $orderBy = "distance ASC";
-                       //$orderBy = "storename ASC";
-                       if ($this->conf['mapAllNoFormView.']['rand']) {
-                           $orderBy = ' rand(now())';
-                               $results_limit = $this->conf['mapAllNoFormView.']['rand'];
-                       }
-
-               } else
-                       $orderBy = "distance ASC";
-
-               if ($this->conf['useFeUserData'] == 1) {
-                       $orderBy = 'tx_locator_toplocation desc, ' . $orderBy;
+               if ($constraint->getRadius() < 2) {
+                       $zoom = 2;
                }
-               if ($this->conf['orderBy'])
-                   $orderBy = $this->conf['orderBy'];
-
 
-               $groupBy = "";
-               $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery($fields, $table, $where_clause, $groupBy, $orderBy, $results_limit);
-               $i = 0;
-               return $result;
-       } // end func
-}
+               $location->setZoom($zoom);
 
-?>
\ No newline at end of file
+               return $location;
+       }
+}
\ No newline at end of file
index b3320d3..b507415 100644 (file)
@@ -23,8 +23,10 @@ namespace Evoweb\StoreFinder\Domain\Model;
  * This copyright notice MUST APPEAR in all copies of the script!
  ***************************************************************/
 
+/**
+ * Class Attribute
+ *
+ * @package Evoweb\StoreFinder\Domain\Model
+ */
 class Attribute extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {
-
-}
-
-?>
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/Classes/Domain/Model/Category.php b/Classes/Domain/Model/Category.php
new file mode 100644 (file)
index 0000000..1fb5954
--- /dev/null
@@ -0,0 +1,65 @@
+<?php
+namespace Evoweb\StoreFinder\Domain\Model;
+/***************************************************************
+ * Copyright notice
+ *
+ * (c) 2013 Sebastian Fischer <typo3@evoweb.de>
+ * All rights reserved
+ *
+ * This script is part of the TYPO3 project. The TYPO3 project is
+ * free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * The GNU General Public License can be found at
+ * http://www.gnu.org/copyleft/gpl.html.
+ *
+ * This script is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+use TYPO3\CMS\Extbase\Persistence\ObjectStorage;
+
+/**
+ * Class Category
+ *
+ * @package Evoweb\StoreFinder\Domain\Model
+ */
+class Category extends \TYPO3\CMS\Extbase\Domain\Model\Category {
+       /**
+        * @var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\Evoweb\StoreFinder\Domain\Model\Category>
+        * @lazy
+        */
+       protected $children;
+
+       /**
+        * Initialize categories, attributed and media relation
+        */
+       public function __construct() {
+               $this->children = new ObjectStorage();
+       }
+
+       /**
+        * Setter
+        *
+        * @param ObjectStorage $children
+        * @return void
+        */
+       public function setChildren($children) {
+               $this->children = $children;
+       }
+
+       /**
+        * Getter
+        *
+        * @return ObjectStorage
+        */
+       public function getChildren() {
+               return $this->children;
+       }
+}
\ No newline at end of file
index 54c34c6..dee73a6 100644 (file)
@@ -23,6 +23,11 @@ namespace Evoweb\StoreFinder\Domain\Model;
  * This copyright notice MUST APPEAR in all copies of the script!
  ***************************************************************/
 
+/**
+ * Class Constraint
+ *
+ * @package Evoweb\StoreFinder\Domain\Model
+ */
 class Constraint extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {
        /**
         * @var string
@@ -70,28 +75,48 @@ class Constraint extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {
        protected $products = '';
 
        /**
-        * @var string
+        * @var array
         */
-       protected $category = '';
+       protected $category = array();
 
        /**
-        * @var integer
+        * @var int
         */
        protected $radius = '';
 
        /**
-        * @var integer
+        * @var int
+        */
+       protected $zoom = 1;
+
+       /**
+        * @var int
         */
        protected $geocode = 0;
 
        /**
+        * @var int
+        */
+       protected $limit = 0;
+
+       /**
+        * @var int
+        */
+       protected $page = 0;
+
+       /**
+        * Setter
+        *
         * @param string $address
+        * @return void
         */
        public function setAddress($address) {
                $this->address = $address;
        }
 
        /**
+        * Getter
+        *
         * @return string
         */
        public function getAddress() {
@@ -99,27 +124,37 @@ class Constraint extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {
        }
 
        /**
-        * @param string $category
+        * Setter
+        *
+        * @param array $category
+        * @return void
         */
        public function setCategory($category) {
-               $this->category = $category;
+               $this->category = (array)$category;
        }
 
        /**
-        * @return string
+        * Getter
+        *
+        * @return array
         */
        public function getCategory() {
-               return $this->category;
+               return (array)$this->category;
        }
 
        /**
+        * Setter
+        *
         * @param string $city
+        * @return void
         */
        public function setCity($city) {
                $this->city = $city;
        }
 
        /**
+        * Getter
+        *
         * @return string
         */
        public function getCity() {
@@ -127,13 +162,18 @@ class Constraint extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {
        }
 
        /**
+        * Setter
+        *
         * @param string $state
+        * @return void
         */
        public function setState($state) {
                $this->state = $state;
        }
 
        /**
+        * Getter
+        *
         * @return string
         */
        public function getState() {
@@ -141,13 +181,18 @@ class Constraint extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {
        }
 
        /**
+        * Setter
+        *
         * @param string $country
+        * @return void
         */
        public function setCountry($country) {
                $this->country = $country;
        }
 
        /**
+        * Getter
+        *
         * @return string
         */
        public function getCountry() {
@@ -155,41 +200,56 @@ class Constraint extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {
        }
 
        /**
+        * Setter
+        *
         * @param string $latitude
+        * @return void
         */
        public function setLatitude($latitude) {
                $this->latitude = $latitude;
        }
 
        /**
+        * Getter
+        *
         * @return string
         */
        public function getLatitude() {
-               return $this->latitude;
+               return $this->latitude ?: '';
        }
 
        /**
+        * Setter
+        *
         * @param string $longitude
+        * @return void
         */
        public function setLongitude($longitude) {
                $this->longitude = $longitude;
        }
 
        /**
+        * Getter
+        *
         * @return string
         */
        public function getLongitude() {
-               return $this->longitude;
+               return $this->longitude ?: '';
        }
 
        /**
+        * Setter
+        *
         * @param string $name
+        * @return void
         */
        public function setName($name) {
                $this->name = $name;
        }
 
        /**
+        * Getter
+        *
         * @return string
         */
        public function getName() {
@@ -197,13 +257,18 @@ class Constraint extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {
        }
 
        /**
+        * Setter
+        *
         * @param string $products
+        * @return void
         */
        public function setProducts($products) {
                $this->products = $products;
        }
 
        /**
+        * Getter
+        *
         * @return string
         */
        public function getProducts() {
@@ -211,27 +276,37 @@ class Constraint extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {
        }
 
        /**
+        * Setter
+        *
         * @param int $radius
+        * @return void
         */
        public function setRadius($radius) {
-               $this->radius = $radius;
+               $this->radius = (int)$radius;
        }
 
        /**
+        * Getter
+        *
         * @return int
         */
        public function getRadius() {
-               return $this->radius;
+               return (int)$this->radius;
        }
 
        /**
+        * Setter
+        *
         * @param string $zipcode
+        * @return void
         */
        public function setZipcode($zipcode) {
                $this->zipcode = $zipcode;
        }
 
        /**
+        * Getter
+        *
         * @return string
         */
        public function getZipcode() {
@@ -239,18 +314,88 @@ class Constraint extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {
        }
 
        /**
+        * Setter
+        *
+        * @param integer $zoom
+        * @return void
+        */
+       public function setZoom($zoom) {
+               $this->zoom = $zoom;
+       }
+
+       /**
+        * Getter
+        *
+        * @return integer
+        */
+       public function getZoom() {
+               return $this->zoom;
+       }
+
+       /**
+        * Setter
+        *
         * @param int $geocode
+        * @return void
         */
        public function setGeocode($geocode) {
                $this->geocode = $geocode;
        }
 
        /**
+        * Getter
+        *
         * @return int
         */
        public function getGeocode() {
                return $this->geocode;
        }
-}
 
-?>
\ No newline at end of file
+       /**
+        * Setter
+        *
+        * @param int $limit
+        * @return void
+        */
+       public function setLimit($limit) {
+               $this->limit = (int)$limit;
+       }
+
+       /**
+        * Getter
+        *
+        * @return int
+        */
+       public function getLimit() {
+               return (int)$this->limit;
+       }
+
+       /**
+        * Setter
+        *
+        * @param int $page
+        * @return void
+        */
+       public function setPage($page) {
+               $this->page = (int)$page;
+       }
+
+       /**
+        * Getter
+        *
+        * @return int
+        */
+       public function getPage() {
+               return (int)$this->page;
+       }
+
+
+       /**
+        * Check if latitude and longitude are set
+        *
+        * @return bool
+        */
+       public function isGeocoded() {
+               return $this->getLatitude() && $this->getLongitude();
+       }
+}
\ No newline at end of file
index 3856599..b0b09bf 100644 (file)
@@ -23,6 +23,13 @@ namespace Evoweb\StoreFinder\Domain\Model;
  * This copyright notice MUST APPEAR in all copies of the script!
  ***************************************************************/
 
+use TYPO3\CMS\Extbase\Persistence\ObjectStorage;
+
+/**
+ * Class Location
+ *
+ * @package Evoweb\StoreFinder\Domain\Model
+ */
 class Location extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {
        /**
         * @var string
@@ -122,7 +129,7 @@ class Location extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {
        /**
         * @var integer
         */
-       protected $useAsCenter = 0;
+       protected $center = 0;
 
        /**
         * @var integer
@@ -136,11 +143,10 @@ class Location extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {
        protected $attributes = '';
 
        /**
-        * var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\Evoweb\StoreFinder\Domain\Model\Category>
-        * @var string
-        * @lazy
-        */
-       protected $categories = '';
+                * @var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\Evoweb\StoreFinder\Domain\Model\Category>
+                * @lazy
+                */
+       protected $categories;
 
        /**
         * var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<Tt_Content>
@@ -184,6 +190,11 @@ class Location extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {
        protected $state = '';
 
        /**
+        * @var double
+        */
+       protected $distance = 0.0;
+
+       /**
         * Initialize categories, attributed and media relation
         */
        public function __construct() {
@@ -191,19 +202,24 @@ class Location extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {
                        $this->categories =
                        $this->content =
                        $this->related =
-                       // $this->image =
-                       // $this->media =
-                               new \TYPO3\CMS\Extbase\Persistence\ObjectStorage();
+                                       // $this->image =
+                                       // $this->media =
+                               new ObjectStorage();
        }
 
        /**
+        * Setter
+        *
         * @param string $additionaladdress
+        * @return void
         */
        public function setAdditionaladdress($additionaladdress) {
                $this->additionaladdress = $additionaladdress;
        }
 
        /**
+        * Getter
+        *
         * @return string
         */
        public function getAdditionaladdress() {
@@ -211,69 +227,94 @@ class Location extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {
        }
 
        /**
+        * Getter
+        *
         * @param string $address
+        * @return void
         */
        public function setAddress($address) {
                $this->address = $address;
        }
 
        /**
+        * Getter
+        *
         * @return string
         */
        public function getAddress() {
-               return $this->address;
+               return $this->escapeJsonString($this->address);
        }
 
        /**
-        * @param \TYPO3\CMS\Extbase\Persistence\ObjectStorage $attributes
+        * Setter
+        *
+        * @param ObjectStorage $attributes
+        * @return void
         */
        public function setAttributes($attributes) {
                $this->attributes = $attributes;
        }
 
        /**
-        * @return \TYPO3\CMS\Extbase\Persistence\ObjectStorage
+        * Getter
+        *
+        * @return ObjectStorage
         */
        public function getAttributes() {
                return $this->attributes;
        }
 
        /**
-        * @param \TYPO3\CMS\Extbase\Persistence\ObjectStorage $categories
+        * Setter
+        *
+        * @param ObjectStorage $categories
+        * @return void
         */
        public function setCategories($categories) {
                $this->categories = $categories;
        }
 
        /**
-        * @return \TYPO3\CMS\Extbase\Persistence\ObjectStorage
+        * Getter
+        *
+        * @return ObjectStorage
         */
        public function getCategories() {
                return $this->categories;
        }
 
        /**
+        * Setter
+        *
         * @param string $city
+        * @return void
         */
        public function setCity($city) {
                $this->city = $city;
        }
 
        /**
+        * Getter
+        *
         * @return string
         */
        public function getCity() {
-               return $this->city;
+               return $this->escapeJsonString($this->city);
        }
 
        /**
+        * Setter
+        *
         * @param string $person
+        * @return void
         */
        public function setPerson($person) {
                $this->person = $person;
        }
 
        /**
+        * Getter
+        *
         * @return string
         */
        public function getPerson() {
@@ -281,13 +322,18 @@ class Location extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {
        }
 
        /**
+        * Setter
+        *
         * @param string $content
+        * @return void
         */
        public function setContent($content) {
                $this->content = $content;
        }
 
        /**
+        * Getter
+        *
         * @return string
         */
        public function getContent() {
@@ -295,13 +341,18 @@ class Location extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {
        }
 
        /**
+        * Setter
+        *
         * @param \SJBR\StaticInfoTables\Domain\Model\Country $country
+        * @return void
         */
        public function setCountry($country) {
                $this->country = $country;
        }
 
        /**
+        * Getter
+        *
         * @return \SJBR\StaticInfoTables\Domain\Model\Country
         */
        public function getCountry() {
@@ -309,6 +360,8 @@ class Location extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {
        }
 
        /**
+        * Getter for country name
+        *
         * @return string
         */
        public function getCountryName() {
@@ -316,13 +369,18 @@ class Location extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {
        }
 
        /**
+        * Setter
+        *
         * @param string $email
+        * @return void
         */
        public function setEmail($email) {
                $this->email = $email;
        }
 
        /**
+        * Getter
+        *
         * @return string
         */
        public function getEmail() {
@@ -330,13 +388,18 @@ class Location extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {
        }
 
        /**
+        * Setter
+        *
         * @param string $fax
+        * @return void
         */
        public function setFax($fax) {
                $this->fax = $fax;
        }
 
        /**
+        * Getter
+        *
         * @return string
         */
        public function getFax() {
@@ -344,13 +407,18 @@ class Location extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {
        }
 
        /**
+        * Setter
+        *
         * @param int $geocode
+        * @return void
         */
        public function setGeocode($geocode) {
                $this->geocode = $geocode;
        }
 
        /**
+        * Getter
+        *
         * @return int
         */
        public function getGeocode() {
@@ -358,27 +426,37 @@ class Location extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {
        }
 
        /**
+        * Setter
+        *
         * @param string $hours
+        * @return void
         */
        public function setHours($hours) {
                $this->hours = $hours;
        }
 
        /**
+        * Getter
+        *
         * @return string
         */
        public function getHours() {
-               return $this->hours;
+               return $this->escapeJsonString($this->hours);
        }
 
        /**
+        * Setter
+        *
         * @param string $icon
+        * @return void
         */
        public function setIcon($icon) {
                $this->icon = $icon;
        }
 
        /**
+        * Getter
+        *
         * @return string
         */
        public function getIcon() {
@@ -386,13 +464,18 @@ class Location extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {
        }
 
        /**
+        * Setter
+        *
         * @param string $image
+        * @return void
         */
        public function setImage($image) {
                $this->image = $image;
        }
 
        /**
+        * Getter
+        *
         * @return string
         */
        public function getImage() {
@@ -400,13 +483,18 @@ class Location extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {
        }
 
        /**
+        * Setter
+        *
         * @param double $latitude
+        * @return void
         */
        public function setLatitude($latitude) {
                $this->latitude = (float) $latitude;
        }
 
        /**
+        * Getter
+        *
         * @return double
         */
        public function getLatitude() {
@@ -414,13 +502,18 @@ class Location extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {
        }
 
        /**
+        * Setter
+        *
         * @param double $longitude
+        * @return void
         */
        public function setLongitude($longitude) {
                $this->longitude = (float) $longitude;
        }
 
        /**
+        * Getter
+        *
         * @return double
         */
        public function getLongitude() {
@@ -428,13 +521,18 @@ class Location extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {
        }
 
        /**
+        * Setter
+        *
         * @param string $media
+        * @return void
         */
        public function setMedia($media) {
                $this->media = $media;
        }
 
        /**
+        * Getter
+        *
         * @return string
         */
        public function getMedia() {
@@ -442,13 +540,18 @@ class Location extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {
        }
 
        /**
+        * Setter
+        *
         * @param string $mobile
+        * @return void
         */
        public function setMobile($mobile) {
                $this->mobile = $mobile;
        }
 
        /**
+        * Getter
+        *
         * @return string
         */
        public function getMobile() {
@@ -456,27 +559,37 @@ class Location extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {
        }
 
        /**
+        * Setter
+        *
         * @param string $notes
+        * @return void
         */
        public function setNotes($notes) {
                $this->notes = $notes;
        }
 
        /**
+        * Getter
+        *
         * @return string
         */
        public function getNotes() {
-               return $this->notes;
+               return $this->escapeJsonString($this->notes);
        }
 
        /**
+        * Setter
+        *
         * @param string $phone
+        * @return void
         */
        public function setPhone($phone) {
                $this->phone = $phone;
        }
 
        /**
+        * Getter
+        *
         * @return string
         */
        public function getPhone() {
@@ -484,13 +597,18 @@ class Location extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {
        }
 
        /**
+        * Setter
+        *
         * @param string $products
+        * @return void
         */
        public function setProducts($products) {
                $this->products = $products;
        }
 
        /**
+        * Getter
+        *
         * @return string
         */
        public function getProducts() {
@@ -498,27 +616,37 @@ class Location extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {
        }
 
        /**
-        * @param \TYPO3\CMS\Extbase\Persistence\ObjectStorage $related
+        * Setter
+        *
+        * @param ObjectStorage $related
+        * @return void
         */
        public function setRelated($related) {
                $this->related = $related;
        }
 
        /**
-        * @return \TYPO3\CMS\Extbase\Persistence\ObjectStorage
+        * Getter
+        *
+        * @return ObjectStorage
         */
        public function getRelated() {
                return $this->related;
        }
 
        /**
+        * Setter
+        *
         * @param \SJBR\StaticInfoTables\Domain\Model\CountryZone $state
+        * @return void
         */
        public function setState($state) {
                $this->state = $state;
        }
 
        /**
+        * Getter
+        *
         * @return \SJBR\StaticInfoTables\Domain\Model\CountryZone
         */
        public function getState() {
@@ -526,20 +654,27 @@ class Location extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {
        }
 
        /**
-        * @return \SJBR\StaticInfoTables\Domain\Model\CountryZone
+        * Getter state name
+        *
+        * @return string
         */
        public function getStateName() {
                return $this->getState() ? $this->getState()->getNameEn() : '';
        }
 
        /**
+        * Setter
+        *
         * @param string $storeid
+        * @return void
         */
        public function setStoreid($storeid) {
                $this->storeid = $storeid;
        }
 
        /**
+        * Getter
+        *
         * @return string
         */
        public function getStoreid() {
@@ -547,27 +682,37 @@ class Location extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {
        }
 
        /**
+        * Setter
+        *
         * @param string $name
+        * @return void
         */
        public function setName($name) {
                $this->name = $name;
        }
 
        /**
+        * Getter
+        *
         * @return string
         */
        public function getName() {
-               return $this->name;
+               return $this->escapeJsonString($this->name);
        }
 
        /**
+        * Setter
+        *
         * @param string $url
+        * @return void
         */
        public function setUrl($url) {
                $this->url = $url;
        }
 
        /**
+        * Getter
+        *
         * @return string
         */
        public function getUrl() {
@@ -575,13 +720,18 @@ class Location extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {
        }
 
        /**
+        * Setter
+        *
         * @param string $zipcode
+        * @return void
         */
        public function setZipcode($zipcode) {
                $this->zipcode = $zipcode;
        }
 
        /**
+        * Getter
+        *
         * @return string
         */
        public function getZipcode() {
@@ -589,32 +739,83 @@ class Location extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {
        }
 
        /**
-        * @param int $useAsCenter
+        * Setter
+        *
+        * @param bool $center
+        * @return void
         */
-       public function setUseAsCenter($useAsCenter) {
-               $this->useAsCenter = $useAsCenter;
+       public function setCenter($center) {
+               $this->center = $center;
        }
 
        /**
-        * @return int
+        * Getter
+        *
+        * @return bool
         */
-       public function getUseAsCenter() {
-               return $this->useAsCenter;
+       public function getCenter() {
+               return (bool)$this->center;
        }
 
        /**
+        * Setter
+        *
+        * @param float $distance
+        * @return void
+        */
+       public function setDistance($distance) {
+               $this->distance = $distance;
+       }
+
+       /**
+        * Getter
+        *
+        * @return float
+        */
+       public function getDistance() {
+               return $this->distance;
+       }
+
+
+       /**
+        * Setter
+        *
         * @param integer $zoom
+        * @return void
         */
        public function setZoom($zoom) {
                $this->zoom = $zoom;
        }
 
        /**
+        * Getter
+        *
         * @return integer
         */
        public function getZoom() {
                return $this->zoom;
        }
-}
 
-?>
\ No newline at end of file
+
+       /**
+        * Escape values for json
+        *
+        * @param string $value
+        * @return mixed
+        */
+       protected function escapeJsonString($value) {
+               $escapers = array('\\', '/', '"', "\n", "\r", "\t", "\x08", "\x0c", "'");
+               $replacements = array('\\\\', '\\/', '\\"', "\\n", "\\r", "\\t", "\\f", '\\b', "\'");
+               $result = str_replace($escapers, $replacements, $value);
+               return $result;
+       }
+
+       /**
+        * Check if location has latitude and longitude
+        *
+        * @return bool
+        */
+       public function isGeocoded() {
+               return $this->getLatitude() && $this->getLongitude();
+       }
+}
\ No newline at end of file
diff --git a/Classes/Domain/Model/Zipcodearea.php b/Classes/Domain/Model/Zipcodearea.php
deleted file mode 100644 (file)
index a575401..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-<?php
-namespace Evoweb\StoreFinder\Domain\Model;
-/***************************************************************
- * Copyright notice
- *
- * (c) 2013 Sebastian Fischer <typo3@evoweb.de>
- * All rights reserved
- *
- * This script is part of the TYPO3 project. The TYPO3 project is
- * free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The GNU General Public License can be found at
- * http://www.gnu.org/copyleft/gpl.html.
- *
- * This script is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * This copyright notice MUST APPEAR in all copies of the script!
- ***************************************************************/
-
-class Zipcodearea extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {
-
-}
-
-?>
\ No newline at end of file
diff --git a/Classes/Domain/Repository/CategoryRepository.php b/Classes/Domain/Repository/CategoryRepository.php
new file mode 100644 (file)
index 0000000..0db0d0f
--- /dev/null
@@ -0,0 +1,65 @@
+<?php
+namespace Evoweb\StoreFinder\Domain\Repository;
+/***************************************************************
+ * Copyright notice
+ *
+ * (c) 2013 Sebastian Fischer <typo3@evoweb.de>
+ * All rights reserved
+ *
+ * This script is part of the TYPO3 project. The TYPO3 project is
+ * free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * The GNU General Public License can be found at
+ * http://www.gnu.org/copyleft/gpl.html.
+ *
+ * This script is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Extbase\Persistence\Generic\Typo3QuerySettings;
+
+/**
+ * Class CategoryRepository
+ *
+ * @package Evoweb\StoreFinder\Domain\Repository
+ */
+class CategoryRepository extends \TYPO3\CMS\Extbase\Domain\Repository\CategoryRepository {
+       /**
+        * Initializes the repository.
+        *
+        * @return void
+        */
+       public function initializeObject() {
+               /** @var $querySettings Typo3QuerySettings */
+               $querySettings = $this->objectManager->get('TYPO3\\CMS\\Extbase\\Persistence\\Generic\\Typo3QuerySettings');
+               $querySettings->setRespectStoragePage(FALSE);
+               $this->setDefaultQuerySettings($querySettings);
+       }
+
+       /**
+        * Find by list or array or uids
+        *
+        * @param array|string $uids
+        * @return array|\TYPO3\CMS\Extbase\Persistence\QueryResultInterface
+        */
+       public function findByUids($uids) {
+               $query = $this->createQuery();
+
+               if (!is_array($uids)) {
+                       $uids = GeneralUtility::intExplode(',', $uids);
+               }
+
+               $query->setOrderings(array('sorting' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_ASCENDING));
+               $query->matching($query->in('uid', $uids));
+
+               return $query->execute();
+       }
+}
\ No newline at end of file
diff --git a/Classes/Domain/Repository/CountryRepository.php b/Classes/Domain/Repository/CountryRepository.php
new file mode 100644 (file)
index 0000000..a8598fa
--- /dev/null
@@ -0,0 +1,77 @@
+<?php
+namespace Evoweb\StoreFinder\Domain\Repository;
+/***************************************************************
+ * Copyright notice
+ *
+ * (c) 2011-13 Sebastian Fischer <typo3@evoweb.de>
+ * All rights reserved
+ *
+ * This script is part of the TYPO3 project. The TYPO3 project is
+ * free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * The GNU General Public License can be found at
+ * http://www.gnu.org/copyleft/gpl.html.
+ *
+ * This script is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+/**
+ * A repository for static info tables country
+ */
+class CountryRepository extends \SJBR\StaticInfoTables\Domain\Repository\CountryRepository {
+       /**
+        * Constructs a new Repository
+        *
+        * @param \TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager
+        * @return self
+        */
+       public function __construct(\TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager) {
+               $this->objectManager = $objectManager;
+
+               $nsSeparator = strpos($this->getRepositoryClassName(), '\\') !== FALSE ? '\\\\' : '_';
+               $this->objectType = preg_replace(
+                       array('/' . $nsSeparator . 'Repository' . $nsSeparator . '(?!.*' . $nsSeparator . 'Repository' . $nsSeparator . ')/', '/Repository$/'),
+                       array($nsSeparator . 'Model' . $nsSeparator, ''),
+                       get_parent_class($this)
+               );
+       }
+
+       /**
+        * Find all countries despecting the storage page
+        *
+        * @return \TYPO3\CMS\Extbase\Persistence\Generic\QueryResult
+        */
+       public function findAll() {
+               $query = $this->createQuery();
+               $query
+                       ->getQuerySettings()
+                       ->setRespectStoragePage(FALSE);
+
+               return $query->execute();
+       }
+
+       /**
+        * Find countries by iso2 codes despection the storage page
+        *
+        * @param array $isoCodeA2
+        * @return \TYPO3\CMS\Extbase\Persistence\Generic\QueryResult
+        */
+       public function findByIsoCodeA2(array $isoCodeA2) {
+               $query = $this->createQuery();
+               $query
+                       ->getQuerySettings()
+                       ->setRespectStoragePage(FALSE);
+
+               $query->matching($query->in('isoCodeA2', $isoCodeA2));
+
+               return $query->execute();
+       }
+}
\ No newline at end of file
index a244025..e101a1e 100644 (file)
@@ -23,6 +23,15 @@ namespace Evoweb\StoreFinder\Domain\Repository;
  * This copyright notice MUST APPEAR in all copies of the script!
  ***************************************************************/
 
+use TYPO3\CMS\Backend\Utility\BackendUtility;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Extbase\Persistence\QueryInterface;
+
+/**
+ * Class LocationRepository
+ *
+ * @package Evoweb\StoreFinder\Domain\Repository
+ */
 class LocationRepository extends \TYPO3\CMS\Extbase\Persistence\Repository  {
        /**
         * Natural logarithm of 2
@@ -49,6 +58,8 @@ class LocationRepository extends \TYPO3\CMS\Extbase\Persistence\Repository  {
        protected $settings = array();
 
        /**
+        * Setter
+        *
         * @param array $settings
         * @return void
         */
@@ -57,29 +68,196 @@ class LocationRepository extends \TYPO3\CMS\Extbase\Persistence\Repository  {
        }
 
        /**
+        * Find locations by contraint
+        *
+        * @param \Evoweb\StoreFinder\Domain\Model\Constraint $constraint
+        * @return \TYPO3\CMS\Extbase\Persistence\QueryResultInterface|array
+        */
+       public function findByConstraint($constraint) {
+               /** @var \TYPO3\CMS\Extbase\Persistence\Generic\Query $query */
+               $query = $this->createQuery();
+
+               if (!$constraint->isGeocoded()) {
+                       return array();
+               }
+
+               $queryParts = array(
+                       'SELECT' => '
+                               distinct l.*,
+                               (acos(
+                                       sin(' . $constraint->getLatitude() * M_PI . ' / 180) *
+                                       sin(latitude * ' . M_PI . ' / 180) +
+                                       cos(' . $constraint->getLatitude() * M_PI . ' / 180) *
+                                       cos(latitude * ' . M_PI . ' / 180) *
+                                       cos((' . $constraint->getLongitude() . ' - longitude) * ' . M_PI . ' / 180)
+                               ) * 6370) as distance',
+                       'FROM' => 'tx_storefinder_domain_model_location l',
+                       'WHERE' => 'l.pid IN (' . implode(',', $query->getQuerySettings()->getStoragePageIds()) . ')' .
+                               $this->getWhereClauseForEnabledFields('tx_storefinder_domain_model_location', 'l'),
+                       'GROUPBY' => '',
+                       'ORDERBY' => 'distance',
+                       'LIMIT' => '',
+               );
+
+               $queryParts = $this->addCountryQueryPart($constraint, $queryParts);
+               $queryParts = $this->addCategoryQueryPart($constraint, $queryParts);
+               $queryParts = $this->addRadiusQueryPart($constraint, $queryParts);
+               $queryParts = $this->addLimitQueryParts($constraint, $queryParts);
+
+               /** @var \TYPO3\CMS\Core\Database\DatabaseConnection $database */
+               $database = $GLOBALS['TYPO3_DB'];
+
+               $sql = $database->SELECTquery($queryParts['SELECT'], $queryParts['FROM'], $queryParts['WHERE'], $queryParts['GROUPBY'], $queryParts['ORDERBY'], $queryParts['LIMIT']);
+               $query->statement($sql);
+
+               return $query->execute();
+       }
+
+       /**
+        * Adds country to query parts if present in contraints
+        *
+        * @param \Evoweb\StoreFinder\Domain\Model\Constraint $constraint
+        * @param array $queryParts
+        * @return array
+        */
+       protected function addCountryQueryPart($constraint, $queryParts) {
+               /** @var \TYPO3\CMS\Core\Database\DatabaseConnection $database */
+               $database = $GLOBALS['TYPO3_DB'];
+
+               if ($constraint->getCountry()) {
+                       $queryParts['FROM'] .= ' INNER JOIN static_countries sc ON (l.country = sc.cn_short_en)';
+                       $queryParts['WHERE'] .= ' AND sc.' . (is_int($constraint->getCountry()) ? 'uid = ' : 'cn_iso_3 = ') . $database->fullQuoteStr(strtoupper($constraint->getCountry()), 'static_countries');
+               }
+
+               return $queryParts;
+       }
+
+       /**
+        * Adds categories to query parts if present in contraints
+        *
+        * @param \Evoweb\StoreFinder\Domain\Model\Constraint $constraint
+        * @param array $queryParts
+        * @return array
+        */
+       protected function addCategoryQueryPart($constraint, $queryParts) {
+               /** @var \TYPO3\CMS\Core\Database\DatabaseConnection $database */
+               $database = $GLOBALS['TYPO3_DB'];
+
+               if ($this->settings['categoryPriority'] == 'limitResultsToCategories') {
+                       $constraint->setCategory(GeneralUtility::intExplode(',', $this->settings['categories'], 1));
+               } elseif ($this->settings['categoryPriority'] == 'useSelectedCategoriesIfNoFilterSelected' && !count($constraint->getCategory())) {
+                       $constraint->setCategory(GeneralUtility::intExplode(',', $this->settings['categories'], 1));
+               }
+
+               $categories = $this->fetchCategoriesRecursive($constraint->getCategory());
+
+               if (!empty($categories)) {
+                       $queryParts['FROM'] .= ' INNER JOIN sys_category_record_mm c ON (l.uid = c.uid_foreign AND c.tablenames = \'tx_storefinder_domain_model_location\' AND c.fieldname = \'categories\')';
+                       $queryParts['WHERE'] .= ' AND c.uid_local IN (' . implode(',', $database->cleanIntArray($categories)) . ')';
+               }
+
+               return $queryParts;
+       }
+
+       /**
+        * Adds radius to query parts if present in contraints
+        *
+        * @param \Evoweb\StoreFinder\Domain\Model\Constraint $constraint
+        * @param array $queryParts
+        * @return array
+        */
+       protected function addRadiusQueryPart($constraint, $queryParts) {
+               /** @var \TYPO3\CMS\Core\Database\DatabaseConnection $database */
+               $database = $GLOBALS['TYPO3_DB'];
+
+               if ($this->settings['distanceUnit'] == 'miles') {
+                       $constraint->setRadius(max($constraint->getRadius(), 1) * 1.6);
+               }
+               $queryParts['WHERE'] .= ' HAVING distance <= ' . $database->fullQuoteStr($constraint->getRadius(), '');
+
+               return $queryParts;
+       }
+
+       /**
+        * Add limit to query parts
+        *
+        * @param \Evoweb\StoreFinder\Domain\Model\Constraint $constraint
+        * @param array $queryParts
+        * @return array
+        */
+       protected function addLimitQueryParts($constraint, $queryParts) {
+               $limit = (int)$this->settings['limit'];
+               $page = 0;
+
+               if ($constraint->getLimit()) {
+                       $limit = $constraint->getLimit();
+               }
+
+               if ($constraint->getPage()) {
+                       $page = $constraint->getPage() * $limit;
+               }
+
+               if ($limit) {
+                       $queryParts['LIMIT'] = $page . ',' . $limit;
+               }
+
+               return $queryParts;
+       }
+
+       /**
+        * Fetch categories recursive
+        *
+        * @param array|int $subcategories
+        * @param array $categories
+        * @return array
+        */
+       protected function fetchCategoriesRecursive(array $subcategories, $categories = array()) {
+               /** @var CategoryRepository $categoryRepository */
+               $categoryRepository = $this->objectManager->get('Evoweb\\StoreFinder\\Domain\\Repository\\CategoryRepository');
+
+               /** @var \Evoweb\StoreFinder\Domain\Model\Category $subcategory */
+               foreach ($subcategories as $subcategory) {
+                       $categories[] = $subcategoryUid = (int)(is_object($subcategory) ? $subcategory->getUid() : $subcategory);
+
+                       /** @noinspection PhpUndefinedMethodInspection */
+                       /** @var \TYPO3\CMS\Extbase\Persistence\Generic\QueryResult $foundCategories */
+                       $foundCategories = $categoryRepository->findByParent($subcategoryUid);
+                       $foundCategories->rewind();
+
+                       $categories = $this->fetchCategoriesRecursive($foundCategories->toArray(), $categories);
+               }
+
+               return array_unique($categories);
+       }
+
+
+       /**
+        * Find center for latitude and longitude
+        *
         * @return \Evoweb\StoreFinder\Domain\Model\Location
         */
-       public function findCenter() {
+       public function findCenterByLatitudeAndLongitude() {
                /** @var \TYPO3\CMS\Extbase\Persistence\Generic\Query $query */
                $query = $this->createQuery();
 
-               $query->setOrderings(array('latitude' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_ASCENDING));
+               $query->setOrderings(array('latitude' => QueryInterface::ORDER_ASCENDING));
                /** @var \Evoweb\StoreFinder\Domain\Model\Location $minLatitude south */
                $minLatitude = $query->execute()->getFirst();
 
-                       // only search for the other locations if first succed or else we have no locations at all
+               // only search for the other locations if first succed or else we have no
+               // locations at all
                if ($minLatitude === NULL) {
                        $maxLatitude = $minLongitute = $maxLongitute = NULL;
                } else {
-                       $query->setOrderings(array('latitude' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_DESCENDING));
+                       $query->setOrderings(array('latitude' => QueryInterface::ORDER_DESCENDING));
                        /** @var \Evoweb\StoreFinder\Domain\Model\Location $maxLatitude north */
                        $maxLatitude = $query->execute()->getFirst();
 
-                       $query->setOrderings(array('longitude' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_ASCENDING));
+                       $query->setOrderings(array('longitude' => QueryInterface::ORDER_ASCENDING));
                        /** @var \Evoweb\StoreFinder\Domain\Model\Location $minLongitute west */
                        $minLongitute = $query->execute()->getFirst();
 
-                       $query->setOrderings(array('longitude' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_DESCENDING));
+                       $query->setOrderings(array('longitude' => QueryInterface::ORDER_DESCENDING));
                        /** @var \Evoweb\StoreFinder\Domain\Model\Location $maxLongitute east */
                        $maxLongitute = $query->execute()->getFirst();
                }
@@ -89,7 +267,8 @@ class LocationRepository extends \TYPO3\CMS\Extbase\Persistence\Repository  {
                $latitudeZoom = $longitudeZoom = 0;
 
                /**
-                * http://stackoverflow.com/questions/6048975/google-maps-v3-how-to-calculate-the-zoom-level-for-a-given-bounds
+                * http://stackoverflow.com/questions/6048975
+                *      /google-maps-v3-how-to-calculate-the-zoom-level-for-a-given-bounds
                 */
                if ($minLatitude !== NULL && $maxLatitude !== NULL) {
                        $location->setLatitude(($maxLatitude->getLatitude() + $minLatitude->getLatitude()) / 2);
@@ -112,6 +291,23 @@ class LocationRepository extends \TYPO3\CMS\Extbase\Persistence\Repository  {
        }
 
        /**
+        * Find one location that is flagged as center
+        *
+        * @return \Evoweb\StoreFinder\Domain\Model\Location
+        */
+       public function findOneByCenter() {
+               /** @var \TYPO3\CMS\Extbase\Persistence\Generic\Query $query */
+               $query = $this->createQuery();
+
+               $query->setOrderings(array('sorting' => QueryInterface::ORDER_ASCENDING));
+               $query->matching('center', 1);
+
+               return $query->execute()->getFirst();
+       }
+
+       /**
+        * Rad method for latitude calculation
+        *
         * @param float $latitude
         * @return string
         */
@@ -122,6 +318,8 @@ class LocationRepository extends \TYPO3\CMS\Extbase\Persistence\Repository  {
        }
 
        /**
+        * Calculate the map radius
+        *
         * @param integer $mapPx
         * @param integer $worldPx
         * @param float $fraction
@@ -130,6 +328,29 @@ class LocationRepository extends \TYPO3\CMS\Extbase\Persistence\Repository  {
        protected function zoom($mapPx, $worldPx, $fraction) {
                return floor(log($mapPx / $worldPx / $fraction) / self::MATH_LN2);
        }
-}
 
-?>
\ No newline at end of file
+       /**
+        * Get where clause for enable fields
+        *
+        * @param string $table
+        * @param string $replacement
+        * @return string
+        */
+       protected function getWhereClauseForEnabledFields($table, $replacement = '') {
+               if (TYPO3_MODE === 'FE') {
+                               // frontend context
+                       $whereClause = $GLOBALS['TSFE']->sys_page->enableFields($table);
+                       $whereClause .= $GLOBALS['TSFE']->sys_page->deleteClause($table);
+               } else {
+                               // backend context
+                       $whereClause = BackendUtility::BEenableFields($table);
+                       $whereClause .= BackendUtility::deleteClause($table);
+               }
+
+               if ($replacement) {
+                       $whereClause = str_replace($table, $replacement, $whereClause);
+               }
+
+               return $whereClause;
+       }
+}
\ No newline at end of file
diff --git a/Classes/Domain/Repository/SessionRepository.php b/Classes/Domain/Repository/SessionRepository.php
new file mode 100644 (file)
index 0000000..a52275b
--- /dev/null
@@ -0,0 +1,76 @@
+<?php
+namespace Evoweb\StoreFinder\Domain\Repository;
+/***************************************************************
+ * Copyright notice
+ *
+ * (c) 2014 Sebastian Fischer <typo3@evoweb.de>
+ * All rights reserved
+ *
+ * This script is part of the TYPO3 project. The TYPO3 project is
+ * free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * The GNU General Public License can be found at
+ * http://www.gnu.org/copyleft/gpl.html.
+ *
+ * This script is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+use Evoweb\StoreFinder\Domain\Model;
+
+/**
+ * Class SessionRepository
+ *
+ * @package Evoweb\StoreFinder\Domain\Repository
+ */
+class SessionRepository {
+       /**
+        * @var \TYPO3\CMS\Frontend\Authentication\FrontendUserAuthentication
+        */
+       protected $frontendUser;
+
+       /**
+        * Constructor
+        *
+        * @return self
+        */
+       public function __construct() {
+               $this->frontendUser = $GLOBALS['TSFE']->fe_user;
+       }
+
+       /**
+        * Get coordinate by hash
+        *
+        * @param string $hash
+        * @return Model\Constraint|Model\Location|bool
+        */
+       public function getCoordinateByHash($hash) {
+               $sessionData = $this->frontendUser->getKey('ses', 'tx_storefinder_coordinates');
+
+               $coordinate = isset($sessionData[$hash]) ? unserialize($sessionData[$hash]) : FALSE;
+
+               return $coordinate;
+       }
+
+       /**
+        * Add calculated coordinate for hash
+        *
+        * @param Model\Constraint|Model\Location $coordinate
+        * @param string $hash
+        * @return void
+        */
+       public function addCoordinateForHash($coordinate, $hash) {
+               $sessionData = $this->frontendUser->getKey('ses', 'tx_storefinder_coordinates');
+               $sessionData[$hash] = serialize($coordinate);
+
+               $this->frontendUser->setKey('ses', 'tx_storefinder_coordinates', $sessionData);
+               $this->frontendUser->storeSessionData();
+       }
+}
\ No newline at end of file
diff --git a/Classes/Domain/Repository/StaticCountryRepository.php b/Classes/Domain/Repository/StaticCountryRepository.php
deleted file mode 100644 (file)
index 28c4849..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-<?php
-namespace Evoweb\StoreFinder\Domain\Repository;
-/***************************************************************
- * Copyright notice
- *
- * (c) 2011-13 Sebastian Fischer <typo3@evoweb.de>
- * All rights reserved
- *
- * This script is part of the TYPO3 project. The TYPO3 project is
- * free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * The GNU General Public License can be found at
- * http://www.gnu.org/copyleft/gpl.html.
- *
- * This script is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * This copyright notice MUST APPEAR in all copies of the script!
- ***************************************************************/
-
-/**
- * A repository for static info tables country
- */
-class StaticCountryRepository extends \TYPO3\CMS\Extbase\Persistence\Repository {
-       /**
-        * Find all countries despecting the storage page
-        *
-        * @return \TYPO3\CMS\Extbase\Persistence\Generic\QueryResult
-        */
-       public function findAll() {
-               $query = $this->createQuery();
-               $query
-                       ->getQuerySettings()
-                       ->setRespectStoragePage(FALSE);
-
-               return $query->execute();
-       }
-
-       /**
-        * Find countries by iso2 codes despection the storage page
-        *
-        * @param array $cnIso2
-        * @return \TYPO3\CMS\Extbase\Persistence\Generic\QueryResult
-        */
-       public function findByCnIso2(array $cnIso2) {
-               $query = $this->createQuery();
-               $query
-                       ->getQuerySettings()
-                       ->setRespectStoragePage(FALSE);
-
-               $query->matching($query->in('cn_iso_2', $cnIso2));
-
-               return $query->execute();
-       }
-}
-
-?>
\ No newline at end of file
index ccc231a..1b13e55 100644 (file)
@@ -23,6 +23,15 @@ namespace Evoweb\StoreFinder\Hook;
  *  This copyright notice MUST APPEAR in all copies of the script!
  ***************************************************************/
 
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use Evoweb\StoreFinder\Domain\Model\Location;
+use TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager;
+
+/**
+ * Class TceMainHook
+ *
+ * @package Evoweb\StoreFinder\Hook
+ */
 class TceMainHook {
        /**
         * @var array
@@ -40,18 +49,21 @@ class TceMainHook {
        protected $repository = NULL;
 
        /**
+        * After database operations hook
+        *
         * @param string $status
         * @param string $table
         * @param string $id
         * @param array $fieldArray
         * @param \TYPO3\CMS\Core\DataHandling\DataHandler $parentObject
+        * @return void
         */
        public function processDatamap_afterDatabaseOperations($status, $table, $id, $fieldArray, $parentObject) {
-               $id = $this->remapId($id, $table, $parentObject);
-
                if ($table === 'tx_storefinder_domain_model_location') {
+                       $locationId = $this->remapId($id, $table, $parentObject);
+
                        $this->initializeConfiguration();
-                       $location = $this->fetchLocation($id);
+                       $location = $this->fetchLocation($locationId);
 
                        if ($location !== NULL) {
                                $this->storeLocation($this->setCoordinates($location));
@@ -60,8 +72,10 @@ class TceMainHook {
        }
 
        /**
+        * Remap id for id and table
+        *
         * @param string $id
-        * @param string $table
+        * @param string &$table
         * @param \TYPO3\CMS\Core\DataHandling\DataHandler $parentObject
         * @return integer
         */
@@ -75,62 +89,75 @@ class TceMainHook {
        }
 
        /**
+        * Initialization of configurations
+        *
         * @return void
         */
        protected function initializeConfiguration() {
-               $this->configuration = \Evoweb\StoreFinder\Utility\ExtensionConfiguration::getConfiguration();
+               $this->configuration = \Evoweb\StoreFinder\Utility\ExtensionConfigurationUtility::getConfiguration();
        }
 
+
        /**
+        * Fetch location for uid
+        *
         * @param integer $uid
-        * @return \Evoweb\StoreFinder\Domain\Model\Location
+        * @return Location
         */
        protected function fetchLocation($uid) {
                return $this->getRepository()->findByUid($uid);
        }
 
        /**
+        * Getter for repository
+        *
         * @return \Evoweb\StoreFinder\Domain\Repository\LocationRepository
         */
        protected function getRepository() {
                if ($this->repository === NULL) {
-                       $this->repository = $this->getObjectManager()->get('Evoweb\StoreFinder\Domain\Repository\LocationRepository');
+                       $this->repository = $this->getObjectManager()->get('Evoweb\\StoreFinder\\Domain\\Repository\\LocationRepository');
                }
 
                return $this->repository;
        }
 
        /**
+        * Getter for object manager
+        *
         * @return \TYPO3\CMS\Extbase\Object\ObjectManager
         */
        protected function getObjectManager() {
                if ($this->objectManager === NULL) {
-                       $this->objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\CMS\Extbase\Object\ObjectManager');
+                       $this->objectManager = GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager');
                }
 
                return $this->objectManager;
        }
 
+
        /**
-        * @param \Evoweb\StoreFinder\Domain\Model\Location $location
-        * @return \Evoweb\StoreFinder\Domain\Model\Location
+        * Sets coordinates by using geocoding service
+        *
+        * @param Location $location
+        * @return Location
         */
-       protected function setCoordinates(\Evoweb\StoreFinder\Domain\Model\Location $location) {
+       protected function setCoordinates(Location $location) {
                return $this->getObjectManager()
-                       ->get('Evoweb\StoreFinder\Service\GeocodeService', $this->configuration)
+                       ->get('Evoweb\\StoreFinder\\Service\\GeocodeService', $this->configuration)
                        ->geocodeAddress($location);
        }
 
        /**
-        * @param \Evoweb\StoreFinder\Domain\Model\Location $location
+        * Stores location
+        *
+        * @param Location $location
         * @return void
         */
-       protected function storeLocation(\Evoweb\StoreFinder\Domain\Model\Location $location) {
+       protected function storeLocation(Location $location) {
                $this->getRepository()->update($location);
-               /** @var \TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager $persistanceManager */
-               $persistanceManager = $this->getObjectManager()->get('TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager');
+
+               /** @var PersistenceManager $persistanceManager */
+               $persistanceManager = $this->getObjectManager()->get('TYPO3\\CMS\\Extbase\\Persistence\\Generic\\PersistenceManager');
                $persistanceManager->persistAll();
        }
-}
-
-?>
\ No newline at end of file
+}
\ No newline at end of file
index fa27eff..5b4585c 100644 (file)
@@ -23,6 +23,14 @@ namespace Evoweb\StoreFinder\Service;
  *  This copyright notice MUST APPEAR in all copies of the script!
  ***************************************************************/
 
+use Evoweb\StoreFinder\Domain\Model;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+
+/**
+ * Class GeocodeService
+ *
+ * @package Evoweb\StoreFinder\Service
+ */
 class GeocodeService {
        /**
         * @var array
@@ -30,7 +38,10 @@ class GeocodeService {
        protected $settings = array();
 
        /**
+        * Constructor
+        *
         * @param array $settings
+        * @return self
         */
        public function __construct(array $settings = array()) {
                if (count($settings)) {
@@ -39,7 +50,9 @@ class GeocodeService {
        }
 
        /**
-        * @param array $settings
+        * Setter
+        *
+        * @param array &$settings
         * @return void
         */
        public function setSettings(array &$settings) {
@@ -52,15 +65,18 @@ class GeocodeService {
        }
 
        /**
-        * @param \Evoweb\StoreFinder\Domain\Model\Location|\Evoweb\StoreFinder\Domain\Model\Constraint $location
+        * Geocode address
+        *
+        * @param Model\Location|Model\Constraint $location
         * @return mixed
         */
        public function geocodeAddress($location) {
-                       // Main Geocoder
-               $query = $this->prepareQuery($location, array('address', 'zipcode', 'city', 'state_name', 'country_name'));
+               // Main Geocoder
+               $query = $this->prepareQuery($location, array('address', 'zipcode', 'city', 'state', 'country'));
                $coordinate = $this->getCoordinateByQuery($query);
 
-                       // If there is no coordinat yet, we assume it's international and attempt to find it based on just the city and country.
+               // If there is no coordinat yet, we assume it's international and attempt
+               // to find it based on just the city and country.
                if (!$coordinate->lat && !$coordinate->lng) {
                        $query = $this->prepareQuery($location, array('city', 'country'));
                        $coordinate = $this->getCoordinateByQuery($query);
@@ -75,7 +91,9 @@ class GeocodeService {
        }
 
        /**
-        * @param \Evoweb\StoreFinder\Domain\Model\Location|\Evoweb\StoreFinder\Domain\Model\Constraint $location
+        * Prepare query
+        *
+        * @param Model\Location|Model\Constraint $location
         * @param array $fields
         * @return array
         */
@@ -85,7 +103,28 @@ class GeocodeService {
                foreach ($fields as $field) {
                        $methodName = 'get' . str_replace(' ', '', ucwords(str_replace('_', ' ', $field)));
                        $value = $location->{$methodName}();
-                       if (!is_object($value) && !is_array($value)) {
+
+                       switch ($field) {
+                               // if a known country code is used we fetch the english shortname
+                               // to enhance the map api query result
+                               case 'country':
+                                       if (is_int($value) || strlen($value) == 3) {
+                                               /** @var \TYPO3\CMS\Core\Database\DatabaseConnection $database */
+                                               $database = $GLOBALS['TYPO3_DB'];
+                                               $country = $database->exec_SELECTgetSingleRow(
+                                                       'cn_short_en',
+                                                       'static_countries',
+                                                       (is_int($value) ? 'uid = ' : 'cn_iso_3 = ') . $database->fullQuoteStr($value, 'static_countries')
+                                               );
+                                               if (count($country)) {
+                                                       $value = reset($country);
+                                               }
+                                       }
+                                       break;
+
+                               default:
+                       }
+                       if (!empty($value) && !is_object($value) && !is_array($value)) {
                                $query[$field] = urlencode($value);
                        }
                }
@@ -94,14 +133,16 @@ class GeocodeService {
        }
 
        /**
+        * Get coordinates by query google maps api
+        *
         * @param array $parameter
         * @return \stdClass
         */
        protected function getCoordinateByQuery($parameter) {
-               $apiURL = $this->settings['geocodeUrl'] . '&address=' . implode(',+', $parameter);
-               $addressData = json_decode(utf8_encode(\TYPO3\CMS\Core\Utility\GeneralUtility::getURL($apiURL)));
+               $apiUrl = $this->settings['geocodeUrl'] . '&address=' . implode(',+', $parameter);
+               $addressData = json_decode(utf8_encode(GeneralUtility::getURL($apiUrl)));
 
-               if (property_exists($addressData, 'status') && $addressData->status === 'OK') {
+               if (is_object($addressData) && property_exists($addressData, 'status') && $addressData->status === 'OK') {
                        $result = $addressData->results[0]->geometry->location;
                } else {
                        $result = new \stdClass();
@@ -109,6 +150,4 @@ class GeocodeService {
 
                return $result;
        }
-}
-
-?>
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/Classes/Utility/ExtensionConfiguration.php b/Classes/Utility/ExtensionConfiguration.php
deleted file mode 100644 (file)
index 0058096..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-<?php
-namespace Evoweb\StoreFinder\Utility;
-/***************************************************************
- *  Copyright notice
- *
- *  (c) 2013 Sebastian Fischer <typo3@evoweb.de>
- *  All rights reserved
- *
- *  This script is part of the TYPO3 project. The TYPO3 project is
- *  free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  The GNU General Public License can be found at
- *  http://www.gnu.org/copyleft/gpl.html.
- *
- *  This script is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  This copyright notice MUST APPEAR in all copies of the script!
- ***************************************************************/
-
-/**
- * Provide a way to get the configuration just everywhere
- *
- * @package TYPO3
- * @subpackage store_finder
- */
-class ExtensionConfiguration implements \TYPO3\CMS\Core\SingletonInterface {
-       /**
-        * @var array
-        */
-       protected static $configuration = NULL;
-
-       /**
-        * Returns all configuration.
-        *
-        * @return array
-        */
-       public static function getConfiguration() {
-               if (self::$configuration === NULL) {
-                       self::$configuration = (array) unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['store_finder']);
-               }
-
-               return self::$configuration;
-       }
-}
-
-?>
\ No newline at end of file
diff --git a/Classes/Utility/ExtensionConfigurationUtility.php b/Classes/Utility/ExtensionConfigurationUtility.php
new file mode 100644 (file)
index 0000000..5fdf8a5
--- /dev/null
@@ -0,0 +1,50 @@
+<?php
+namespace Evoweb\StoreFinder\Utility;
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2013 Sebastian Fischer <typo3@evoweb.de>
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+/**
+ * Provide a way to get the configuration just everywhere
+ *
+ * @package TYPO3
+ * @subpackage store_finder
+ */
+class ExtensionConfigurationUtility implements \TYPO3\CMS\Core\SingletonInterface {
+       /**
+        * @var array
+        */
+       protected static $configuration = NULL;
+
+       /**
+        * Returns all configuration.
+        *
+        * @return array
+        */
+       public static function getConfiguration() {
+               if (self::$configuration === NULL) {
+                       self::$configuration = (array) unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['store_finder']);
+               }
+
+               return self::$configuration;
+       }
+}
\ No newline at end of file
diff --git a/Classes/Utility/UpdateUtility.php b/Classes/Utility/UpdateUtility.php
new file mode 100644 (file)
index 0000000..1f58147
--- /dev/null
@@ -0,0 +1,553 @@
+<?php
+namespace Evoweb\StoreFinder\Utility;
+
+/**
+ * Class UpdateUtility
+ *
+ * @package Evoweb\StoreFinder\Utility
+ */
+class UpdateUtility {
+       /**
+        * @var \TYPO3\CMS\Core\Database\DatabaseConnection $database
+        */
+       protected $database;
+
+       /**
+        * @var array
+        */
+       protected $mapping = array(
+               'attributes' => array(
+                       'uid' => 'import_id',
+                       'pid' => 'pid',
+                       'tstamp' => 'tstamp',
+                       'crdate' => 'crdate',
+                       'cruser_id' => 'cruser_id',
+                       'sorting' => 'sorting',
+                       'hidden' => 'hidden',
+                       'deleted' => 'deleted',
+                       'sys_language_uid' => 'sys_language_uid',
+                       'l10n_parent' => 'value:attributes:l10n_parent',
+                       'l10n_diffsource' => 'l10n_diffsource',
+                       'icon' => 'icon',
+                       'name' => 'name',
+               ),
+               'categories' => array(
+                       'uid' => 'import_id',
+                       'pid' => 'pid',
+                       'parentuid' => 'value:categories:parent',
+                       'tstamp' => 'tstamp',
+                       'crdate' => 'crdate',
+                       'cruser_id' => 'cruser_id',
+                       'sorting' => 'sorting',
+                       'hidden' => 'hidden',
+                       'deleted' => 'deleted',
+                       'sys_language_uid' => 'sys_language_uid',
+                       'l10n_parent' => 'value:categories:l10n_parent',
+                       'l10n_diffsource' => 'l10n_diffsource',
+                       'fe_group' => '',
+                       'name' => 'title',
+                       'description' => 'description',
+               ),
+               'locations' => array(
+                       'uid' => 'import_id',
+                       'pid' => 'pid',
+                       'tstamp' => 'tstamp',
+                       'crdate' => 'crdate',
+                       'cruser_id' => 'cruser_id',
+                       'sorting' => 'sorting',
+                       'deleted' => 'deleted',
+                       'hidden' => 'hidden',
+                       'endtime' => 'endtime',
+                       'fe_group' => 'fe_group',
+                       'storename' => 'name',
+                       'storeid' => 'storeid',
+                       'attributes' => 'comma:mm:attributes:tx_storefinder_location_attribute_mm:uid_local:tx_storefinder_domain_model_attribute:attributes',
+                       'address' => 'address',
+                       'additionaladdress' => 'additionaladdress',
+                       'city' => 'city',
+                       'contactperson' => 'person',
+                       'state' => 'state',
+                       'zipcode' => 'zipcode',
+                               // @todo implement 1:1 references for country
+                       'country' => 'ref:country',
+                       'products' => 'products',
+                       'email' => 'email',
+                       'phone' => 'phone',
+                       'mobile' => 'mobile',
+                       'fax' => 'fax',
+                       'hours' => 'hours',
+                       'url' => 'url',
+                       'notes' => 'notes',
+                       'media' => 'media',
+                               // @todo implement fal references for images
+                       'imageurl' => 'ref:image',
+                       'icon' => 'icon',
+                       'content' => 'content',
+                       'use_coordinate' => '',
+                       'categoryuid' => 'comma:mm:categories:sys_category_record_mm:uid_foreign:tx_storefinder_domain_model_location:categories',
+                       'lat' => 'latitude',
+                       'lon' => 'longitude',
+                       'geocode' => '',
+                       'relatedto' => 'finish_comma:mm:locations:tx_storefinder_location_location_mm:uid_local:tx_storefinder_domain_model_location:related',
+               ),
+       );
+
+       /**
+        * @var array
+        */
+       protected $records = array(
+               'attributes' => array(),
+               'categories' => array(),
+               'locations' => array(),
+       );
+
+       /**
+        * @var array
+        */
+       protected $messageArray = array();
+
+
+       /**
+        * Performes the Updates
+        * Outputs HTML Content
+        *
+        * @return string
+        */
+       public function main() {
+               $this->database = $GLOBALS['TYPO3_DB'];
+
+               $content = '';
+
+               if ($this->access()) {
+                       if ($this->warningAccepted()) {
+                               $this->migrateAttributes();
+                               $this->migrateCategories();
+                               $this->migrateLocations();
+                       } else {
+                               $content = $this->renderWarning();
+                       }
+               }
+
+               return $content ?: $this->generateOutput();
+       }
+
+
+       /**
+        * Render warning
+        *
+        * @return string
+        */
+       protected function renderWarning() {
+               $action = \TYPO3\CMS\Core\Utility\GeneralUtility::linkThisScript(array(
+                       'M' => \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('M'),
+                       'tx_extensionmanager_tools_extensionmanagerextensionmanager' =>
+                               \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('tx_extensionmanager_tools_extensionmanagerextensionmanager')
+               ));
+
+               $content = '</br>Do you want to start the migration?</br>
+                       <form action="' . $action . '" method="POST">
+                               <button name="tx_storefinder_update[confirm]" value="1">Start migration</button>
+                       </form>';
+
+               return $content;
+       }
+
+       /**
+        * Check if warning was confirmed
+        *
+        * @return bool
+        */
+       protected function warningAccepted() {
+               $updateVars = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('tx_storefinder_update');
+
+               return (bool)$updateVars['confirm'];
+       }
+
+       /**
+        * Generates output by using flash messages
+        *
+        * @return string
+        */
+       protected function generateOutput() {
+               $output = '';
+
+               foreach ($this->messageArray as $messageItem) {
+                       /** @var \TYPO3\CMS\Core\Messaging\FlashMessage $flashMessage */
+                       $flashMessage = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(
+                               'TYPO3\\CMS\\Core\\Messaging\\FlashMessage',
+                               htmlspecialchars($messageItem['message']),
+                               '',
+                               \TYPO3\CMS\Core\Messaging\FlashMessage::INFO
+                       );
+
+                       $output .= $flashMessage->render();
+               }
+
+               return $output;
+       }
+
+
+       /**
+        * Migrate attributes
+        *
+        * @return void
+        */
+       protected function migrateAttributes() {
+               $attributes = $this->fetchAttributes();
+
+               while (($row = $this->database->sql_fetch_assoc($attributes))) {
+                       $attribute = $this->mapFieldsPreImport($row, 'attributes');
+
+                       $table = 'tx_storefinder_domain_model_attribute';
+                       if (($record = $this->isAlreadyImported($attribute, $table))) {
+                               unset($attribute['import_id']);
+                               $this->database->exec_UPDATEquery($table, 'uid = ' . $record['uid'], $attribute);
+                               $this->records['attributes'][$row['uid']] = $attribute['uid'] = $record['uid'];
+                       } else {
+                               $this->database->exec_INSERTquery($table, $attribute);
+                               $this->records['attributes'][$row['uid']] = $attribute['uid'] = $this->database->sql_insert_id();
+                       }
+               }
+
+               $this->messageArray[] = array('message' => count($this->records['attributes']) . ' attributes migrated');
+       }
+
+       /**
+        * Migrate categories
+        *
+        * @return void
+        */
+       protected function migrateCategories() {
+               $categories = $this->fetchCategories();
+
+               while (($row = $this->database->sql_fetch_assoc($categories))) {
+                       $category = $this->mapFieldsPreImport($row, 'categories');
+
+                       $table = 'sys_category';
+                       if (($record = $this->isAlreadyImported($category, $table))) {
+                               unset($category['import_id']);
+                               $this->database->exec_UPDATEquery($table, 'uid = ' . $record['uid'], $category);
+                               $this->records['categories'][$row['uid']] = $category['uid'] = $record['uid'];
+                       } else {
+                               $this->database->exec_INSERTquery($table, $category);
+                               $this->records['categories'][$row['uid']] = $category['uid'] = $this->database->sql_insert_id();
+                       }
+               }
+
+               $this->messageArray[] = array('message' => count($this->records['categories']) . ' categories migrated');
+       }
+
+       /**
+        * Migrate locations with relations
+        *
+        * @return void
+        */
+       protected function migrateLocations() {
+               $locations = $this->fetchLocations();
+
+               while (($row = $this->database->sql_fetch_assoc($locations))) {
+                       $location = $this->mapFieldsPreImport($row, 'locations');
+
+                       $table = 'tx_storefinder_domain_model_location';
+                       if (($record = $this->isAlreadyImported($location, $table))) {
+                               unset($location['import_id']);
+                               $this->database->exec_UPDATEquery($table, 'uid = ' . $record['uid'], $location);
+                               $this->records['locations'][$row['uid']] = $location['uid'] = $record['uid'];
+                       } else {
+                               $this->database->exec_INSERTquery($table, $location);
+                               $this->records['locations'][$row['uid']] = $location['uid'] = $this->database->sql_insert_id();
+                       }
+
+                       $this->mapFieldsPostImport($row, $location, 'locations');
+               }
+
+               $this->database->sql_query('
+                       update tx_storefinder_domain_model_location AS l
+                               LEFT JOIN (
+                                       SELECT uid_foreign, COUNT(*) AS count
+                                       FROM sys_category_record_mm
+                                       WHERE tablenames = \'tx_storefinder_domain_model_location\' AND fieldname = \'categories\'
+                                       GROUP BY uid_foreign
+                               ) AS c ON l.uid = c.uid_foreign
+                       set l.categories = COALESCE(c.count, 0);
+               ');
+               $this->database->sql_query('
+                       update tx_storefinder_domain_model_location AS l
+                               LEFT JOIN (
+                                       SELECT uid_local, COUNT(*) AS count
+                                       FROM tx_storefinder_location_attribute_mm
+                                       GROUP BY uid_local
+                               ) AS a ON l.uid = a.uid_local
+                       set l.attributes = COALESCE(a.count, 0);
+               ');
+               $this->database->sql_query('
+                       update tx_storefinder_domain_model_location AS l
+                               LEFT JOIN (
+                                       SELECT uid_local, COUNT(*) AS count
+                                       FROM tx_storefinder_location_location_mm
+                                       GROUP BY uid_local
+                               ) AS a ON l.uid = a.uid_local
+                       set l.related = COALESCE(a.count, 0);
+               ');
+
+               $this->messageArray[] = array('message' => count($this->records['locations']) . ' locations migrated');
+       }
+
+
+       /**
+        * Fetch locator attributes
+        *
+        * @return \mysqli_result
+        */
+       protected function fetchAttributes() {
+               return $this->database->exec_SELECTquery(
+                       '*',
+                       'tx_locator_attributes',
+                       'deleted = 0',
+                       '',
+                       'sys_language_uid'
+               );
+       }
+
+       /**
+        * Fetch locator categories
+        *
+        * @return \mysqli_result
+        */
+       protected function fetchCategories() {
+               return $this->database->exec_SELECTquery(
+                       '*',
+                       'tx_locator_categories',
+                       'deleted = 0',
+                       '',
+                       'sys_language_uid, parentuid'
+               );
+       }
+
+       /**
+        * Fetch locator locations
+        *
+        * @return \mysqli_result
+        */
+       protected function fetchLocations() {
+               return $this->database->exec_SELECTquery(
+                       '*',
+                       'tx_locator_locations',
+                       'deleted = 0',
+                       '',
+                       'uid'
+               );
+       }
+
+
+       /**
+        * Map fields pre import
+        *
+        * @param array $row
+        * @param string $table
+        * @return array
+        */
+       protected function mapFieldsPreImport($row, $table) {
+               $result = array();
+
+               foreach ($this->mapping[$table] as $fieldFrom => $fieldTo) {
+                       if ($fieldTo && strpos($fieldTo, ':') === FALSE) {
+                               $result[$fieldTo] = is_null($row[$fieldFrom]) ? (string)$row[$fieldFrom] : $row[$fieldFrom];
+                       } elseif ($fieldTo) {
+                               $parts = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(':', $fieldTo);
+
+                               switch ($parts[0]) {
+                                       case 'value':
+                                               $result[$parts[2]] = (string) $this->records[$parts[1]][$row[$fieldFrom]];
+                                               break;
+
+                                       default:
+                               }
+                       }
+               }
+
+               return $result;
+       }
+
+       /**
+        * Map fields post import
+        *
+        * @param array $source
+        * @param array $destination
+        * @param string $table
+        * @return void
+        */
+       protected function mapFieldsPostImport($source, $destination, $table) {
+               foreach ($this->mapping[$table] as $fieldFrom => $fieldTo) {
+                       if (strpos($fieldTo, ':') !== FALSE) {
+                               $parts = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(':', $fieldTo);
+                               switch ($parts[0]) {
+                                       case 'comma':
+                                               if ($parts[1] == 'mm') {
+                                                       list(,, $sourceModel, $mmTable, $mmField, $destinationTable, $destinationField) = $parts;
+                                                       $sorting = 0;
+
+                                                       foreach (\TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $source[$fieldFrom]) as $fromValue) {
+                                                               if ($mmField == 'uid_local') {
+                                                                       $uidForeign = $this->records[$sourceModel][$fromValue];
+                                                                       $uidLocal = $destination['uid'];
+                                                               } else {
+                                                                       $uidLocal = $this->records[$sourceModel][$fromValue];
+                                                                       $uidForeign = $destination['uid'];
+                                                               }
+
+                                                               if (!$uidLocal || !$uidForeign) {
+                                                                       continue;
+                                                               }
+
+                                                               if (!$this->mmRelationExists($mmTable, $uidLocal, $uidForeign, $destinationTable)) {
+                                                                       $this->database->exec_INSERTquery(
+                                                                               $mmTable,
+                                                                               array(
+                                                                                       'uid_local' => $uidLocal,
+                                                                                       'uid_foreign' => $uidForeign,
+                                                                                       'tablenames' => $destinationTable,
+                                                                                       'sorting' . ($mmField == 'uid_foreign' ? '_foreign' : '') => $sorting,
+                                                                                       'fieldname' => $destinationField,
+                                                                               )
+                                                                       );
+                                                               }
+
+                                                               $sorting++;
+                                                       }
+                                               }
+                                               break;
+
+                                       default:
+                               }
+                       }
+               }
+       }
+
+       /**
+        * Map fields after all records are imported
+        *
+        * @param array $source
+        * @param array $destination
+        * @param string $table
+        * @return void
+        */
+       protected function mapFieldsFinish($source, $destination, $table) {
+               foreach ($this->mapping[$table] as $fieldFrom => $fieldTo) {
+                       if (strpos($fieldTo, ':') !== FALSE) {
+                               $parts = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(':', $fieldTo);
+                               switch (str_replace('finish_', '', $parts[0])) {
+                                       case 'comma':
+                                               if ($parts[1] == 'mm') {
+                                                       list(,, $sourceModel, $mmTable, $mmField, $destinationTable, $destinationField) = $parts;
+                                                       $sorting = 0;
+                                                       foreach (\TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $source[$fieldFrom]) as $fromValue) {
+                                                               if ($mmField == 'uid_local') {
+                                                                       $uidForeign = $this->records[$sourceModel][$fromValue];
+                                                                       $uidLocal = $destination['uid'];
+                                                               } else {
+                                                                       $uidLocal = $this->records[$sourceModel][$fromValue];
+                                                                       $uidForeign = $destination['uid'];
+                                                               }
+
+                                                               if (!$uidLocal || !$uidForeign) {
+                                                                       continue;
+                                                               }
+
+                                                               if (!$this->mmRelationExists($mmTable, $uidLocal, $uidForeign, $destinationTable)) {
+                                                                       $this->database->exec_INSERTquery(
+                                                                               $mmTable,
+                                                                               array(
+                                                                                       'uid_local' => $uidLocal,
+                                                                                       'uid_foreign' => $uidForeign,
+                                                                                       'tablenames' => $destinationTable,
+                                                                                       'sorting' . ($mmField == 'uid_foreign' ? '_foreign' : '') => $sorting,
+                                                                                       'fieldname' => $destinationField,
+                                                                               )
+                                                                       );
+                                                               }
+
+                                                               $sorting++;
+                                                       }
+                                               }
+                                               break;
+
+                                       default:
+                               }
+                       }
+               }
+       }
+
+       /**
+        * Checks if a mm relation exists
+        *
+        * @param string $mmTable
+        * @param int $uidLocal
+        * @param int $uidForeign
+        * @param string $tablenames
+        * @return bool
+        */
+       protected function mmRelationExists($mmTable, $uidLocal, $uidForeign, $tablenames) {
+               return (bool) $this->database->exec_SELECTcountRows(
+                       '*',
+                       $mmTable,
+                       'uid_local = ' . $uidLocal . ' AND uid_foreign = ' . $uidForeign . ' AND tablenames = \'' . $tablenames . '\''
+               );
+       }
+
+       /**
+        * Check if a record is already imported
+        *
+        * @param array $record
+        * @param string $table
+        * @return bool
+        */
+       protected function isAlreadyImported($record, $table) {
+               return $this->database->exec_SELECTgetSingleRow(
+                       'uid',
+                       $table,
+                       'import_id = ' . $record['import_id'] . ' AND deleted = 0'
+               );
+       }
+
+       /**
+        * Count locations
+        *
+        * @return int
+        */
+       protected function countStoreFinderLocations() {
+               return $this->database->exec_SELECTcountRows(
+                       'uid',
+                       'tx_storefinder_domain_model_location',
+                       '1' . \TYPO3\CMS\Backend\Utility\BackendUtility::BEenableFields('tx_storefinder_domain_model_location')
+               );
+       }
+
+       /**
+        * echeck if the Ipdate is neassessary
+        *
+        * @return bool True if update should be perfomed
+        */
+       public function access() {
+               /** @var \TYPO3\CMS\Core\Database\DatabaseConnection $database */
+               $database = $GLOBALS['TYPO3_DB'];
+
+               $countLocations = $database->exec_SELECTcountRows(
+                       'l.uid',
+                       'tx_locator_locations AS l LEFT JOIN tx_storefinder_domain_model_location AS sl ON l.uid = sl.import_id',
+                       'l.deleted = 0'
+               );
+               $countAttributes = $database->exec_SELECTcountRows(
+                       'a.uid',
+                       'tx_locator_attributes AS a LEFT JOIN tx_storefinder_domain_model_attribute AS sa ON a.uid = sa.import_id',
+                       'a.deleted = 0'
+               );
+
+               $result = FALSE;
+               if ($countLocations || $countAttributes) {
+                       $result = TRUE;
+               }
+
+               return $result;
+       }
+}
\ No newline at end of file
diff --git a/Classes/View/SelectTreeview.php b/Classes/View/SelectTreeview.php
deleted file mode 100644 (file)
index 77408db..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
-<?php
-namespace Evoweb\StoreFinder\View;
-/***************************************************************
- *  Copyright notice
- *
- *  (c) 2013 Sebastian Fischer <typo3@evoweb.de>
- *  All rights reserved
- *
- *  This script is part of the TYPO3 project. The TYPO3 project is
- *  free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  The GNU General Public License can be found at
- *  http://www.gnu.org/copyleft/gpl.html.
- *
- *  This script is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  This copyright notice MUST APPEAR in all copies of the script!
- ***************************************************************/
-
-/**
- * extend class t3lib_treeview to change function wrapTitle().
- */
-class SelectTreeview extends \TYPO3\CMS\Backend\Tree\View\AbstractTreeView {
-       /**
-        * @var string
-        */
-       public $TCEforms_itemFormElName = '';
-
-       /**
-        * @var array
-        */
-       public $TCEforms_nonSelectableItemsArray = array();
-
-       /**
-        * @var integer
-        */
-       public $maxDepth;
-
-       /**
-        * @var string
-        */
-       public $hiddenField;
-
-       /**
-        * Needs to be initialized with e.g. $GLOBALS['WEBMOUNTS']
-        * Default setting in init() is 0 => 0
-        * The keys are mount-ids (can be anything basically) and the values are the
-        * ID of the root element (COULD be zero or anything else. For pages that
-        * would be the uid of the page, zero for the pagetree root.)
-        *
-        * @var array
-        */
-       public $MOUNTS = array(0 => 0);
-
-       /**
-        * wraps the record titles in the tree with links or not depending on if they are in the TCEforms_nonSelectableItemsArray.
-        *
-        * @param       string          $title: the title
-        * @param       array           $v: an array with uid and title of the current item.
-        * @return      string          the wrapped title
-        */
-       public function wrapTitle($title, $v) {
-               if ($v['title'] == '') {
-                       $title = $v['name'];
-               }
-
-               $aOnClick = 'setFormValueFromBrowseWin(\'' . $this->TCEforms_itemFormElName . '\',' . $v['uid'] . ',\'' . $title . '\'); return false;';
-               return '<a href="#" onclick="' . htmlspecialchars($aOnClick) . '" title="' . htmlentities($v['description']) . '">' . $title . '</a>';
-       }
-
-       /**
-        * Wrap the plus/minus icon in a link
-        *
-        * @param string $icon HTML string to wrap, probably an image tag.
-        * @param string $cmd Command for 'PM' get var
-        * @param string $bMark If set, the link will have a anchor point (=$bMark) and a name attribute (=$bMark)
-        * @return string Link-wrapped input string
-        * @access private
-        */
-       public function PM_ATagWrap($icon, $cmd, $bMark = '') {
-               if ($this->thisScript) {
-                       $name = '';
-                       if ($bMark) {
-                               $name = ' name="' . $bMark . '"';
-                       }
-                       return '<a href="#" onClick="set' . $this->treeName . 'PM(\'' . $cmd . '\');TBE_EDITOR_submitForm();"' . $name . '>' . $icon . '</a>';
-               } else {
-                       return $icon;
-               }
-       }
-
-       public function initializePositionSaving() {
-                       // Get stored tree structure:
-               $this->stored = unserialize($this->BE_USER->uc['browseTrees'][$this->treeName]);
-
-                       // PM action
-                       // (If an plus/minus icon has been clicked, the PM GET var is sent and we must update the stored positions in the tree):
-                       // 0: mount key, 1: set/clear boolean, 2: item ID (cannot contain "_"), 3: treeName
-               $PM = explode('_', \TYPO3\CMS\Core\Utility\GeneralUtility::_POST($this->treeName . '_pm'));
-
-               if (count($PM) == 4 && $PM[3] == $this->treeName) {
-                       if (isset($this->MOUNTS[$PM[0]])) {
-                                       // set
-                               if ($PM[1]) {
-                                               $this->stored[$PM[0]][$PM[2]] = 1;
-                                               $this->savePosition();
-                                       // clear
-                               } else {
-                                               unset($this->stored[$PM[0]][$PM[2]]);
-                                               $this->savePosition();
-                               }
-                       }
-               }
-       }
-
-       /**
-        * Will create and return the HTML code for a browsable tree
-        * Is based on the mounts found in the internal array ->MOUNTS (set in the constructor)
-        *
-        * @param integer $maxDepth
-        * @return string HTML code for the browsable tree
-        */
-       public function getBrowsableTree($maxDepth = 999) {
-                       // Get stored tree structure AND updating it if needed according to incoming PM GET var.
-               $this->initializePositionSaving();
-
-                       // Init done:
-               $treeArr = array();
-
-                       // Traverse mounts:
-               foreach ($this->MOUNTS as $idx => $uid) {
-
-                               // Set first:
-                       $this->bank = $idx;
-                       $isOpen = $this->stored[$idx][$uid] || $this->expandFirst;
-
-                               // Save ids while resetting everything else.
-                       $curIds = $this->ids;
-                       $this->reset();
-                       $this->ids = $curIds;
-
-                               // Set PM icon for root of mount:
-                       $cmd = $this->bank . '_' . ($isOpen ? '0_' : '1_') . $uid . '_' . $this->treeName;
-                       $icon = '<img' . \TYPO3\CMS\Backend\Utility\IconUtility::skinImg($this->backPath, 'gfx/ol/' . ($isOpen ? 'minus' : 'plus') . 'only.gif', 'width="18" height="16"') . ' alt="" />';
-                       $firstHtml = $this->PM_ATagWrap($icon, $cmd);
-
-                               // Preparing rootRec for the mount
-                       if ($uid) {
-                               $rootRec = $this->getRecord($uid);
-                               $firstHtml .= $this->getIcon($rootRec);
-                       } else {
-                                       // Artificial record for the tree root, id=0
-                               $rootRec = $this->getRootRecord($uid);
-                               $firstHtml .= $this->getRootIcon($rootRec);
-                       }
-
-                       if (is_array($rootRec)) {
-                                       // Add the root of the mount to ->tree
-                               $this->tree[] = array('HTML' => $firstHtml, 'row' => $rootRec, 'bank' => $this->bank);
-
-                                       // If the mount is expanded, go down:
-                               if ($isOpen) {
-                                               // Set depth:
-                                       $depthD = '<img' . \TYPO3\CMS\Backend\Utility\IconUtility::skinImg($this->backPath, 'gfx/ol/blank.gif', 'width="18" height="16"') . ' alt="" />';
-                                       if ($this->addSelfId) {
-                                               $this->ids[] = $uid;
-                                       }
-                                       $this->getTree($uid, $maxDepth, $depthD);
-                               }
-
-                                       // Add tree:
-                               $treeArr = array_merge($treeArr, $this->tree);
-                       }
-               }
-               return $this->printTree($treeArr);
-       }
-}
-
-if (defined('TYPO3_MODE') && $GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['ext/store_finder/Classes/View/SelectTreeview.php']) {
-       /** @noinspection PhpIncludeInspection */
-       include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['ext/store_finder/Classes/View/SelectTreeview.php']);
-}
-
-?>
\ No newline at end of file
diff --git a/Classes/ViewHelpers/Form/SelectCountriesViewHelper.php b/Classes/ViewHelpers/Form/SelectCountriesViewHelper.php
new file mode 100644 (file)
index 0000000..006b72c
--- /dev/null
@@ -0,0 +1,88 @@
+<?php
+namespace Evoweb\StoreFinder\ViewHelpers\Form;
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2013 Sebastian Fischer <typo3@evoweb.de>
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+/**
+ * Viewhelper to render a selectbox with values of static info tables countries
+ *
+ * <code title="Usage">
+ * {namespace register=Evoweb\StoreFinder\ViewHelpers}
+ * <register:form.SelectStaticCountries name="country"
+ *             optionLabelField="cnShortDe"/>
+ * </code>
+ *
+ * <code title="Optional label field">
+ * {namespace register=Evoweb\StoreFinder\ViewHelpers}
+ * <register:form.SelectStaticCountries name="country"
+ *             optionLabelField="cnShortDe"/>
+ * </code>
+ */
+class SelectCountriesViewHelper extends \TYPO3\CMS\Fluid\ViewHelpers\Form\SelectViewHelper {
+       /**
+        * Repository that provides the country models
+        *
+        * @var \Evoweb\StoreFinder\Domain\Repository\CountryRepository
+        * @inject
+        */
+       protected $countryRepository;
+
+       /**
+        * Initialize arguments. Cant be moved to parent because of
+        * "private $argumentDefinitions = array();"
+        *
+        * @return void
+        */
+       public function initializeArguments() {
+               parent::initializeArguments();
+
+               $this->overrideArgument('options', 'object', 'Associative array with internal IDs as key, and the values are displayed in the select box', FALSE);
+               $this->overrideArgument('optionValueField', 'string', 'If specified, will call the appropriate getter on each object to determine the value.', FALSE, 'isoCodeA2');
+               $this->overrideArgument('optionLabelField', 'string', 'If specified, will call the appropriate getter on each object to determine the label.', FALSE, 'shortNameLocal');
+               $this->overrideArgument('sortByOptionLabel', 'boolean', 'If true, List will be sorted by label.', FALSE, TRUE);
+               $this->registerArgument('allowedCountries', 'array', 'Array with countries allowed to be displayed.', FALSE, array());
+       }
+
+       /**
+        * Override the initialize method to load all available
+        * countries before rendering
+        *
+        * @return void
+        */
+       public function initialize() {
+               parent::initialize();
+
+               if (\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded('static_info_tables')) {
+                       if ($this->hasArgument('allowedCountries') && count($this->arguments['allowedCountries'])) {
+                               $result = $this->countryRepository->findByIsoCodeA2($this->arguments['allowedCountries']);
+                       } else {
+                               $result = $this->countryRepository->findAll();
+                       }
+
+                       $this->arguments['options'] = array();
+                       foreach ($result as $country) {
+                               $this->arguments['options'][] = $country;
+                       }
+               }
+       }
+}
\ No newline at end of file
diff --git a/Classes/ViewHelpers/Form/SelectStaticCountriesViewHelper.php b/Classes/ViewHelpers/Form/SelectStaticCountriesViewHelper.php
deleted file mode 100644 (file)
index 6f193d8..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-<?php
-namespace Evoweb\StoreFinder\ViewHelpers\Form;
-/***************************************************************
- *  Copyright notice
- *
- *  (c) 2013 Sebastian Fischer <typo3@evoweb.de>
- *  All rights reserved
- *
- *  This script is part of the TYPO3 project. The TYPO3 project is
- *  free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  The GNU General Public License can be found at
- *  http://www.gnu.org/copyleft/gpl.html.
- *
- *  This script is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  This copyright notice MUST APPEAR in all copies of the script!
- ***************************************************************/
-
-/**
- * Viewhelper to render a selectbox with values of static info tables countries
- *
- * <code title="Usage">
- * {namespace register=Evoweb\StoreFinder\ViewHelpers}
- * <register:form.SelectStaticCountries name="country" optionLabelField="cnShortDe"/>
- * </code>
- *
- * <code title="Optional label field">
- * {namespace register=Evoweb\StoreFinder\ViewHelpers}
- * <register:form.SelectStaticCountries name="country" optionLabelField="cnShortDe"/>
- * </code>
- */
-class SelectStaticCountriesViewHelper extends \TYPO3\CMS\Fluid\ViewHelpers\Form\SelectViewHelper {
-       /**
-        * Repository that provides the country models
-        *
-        * @var \Evoweb\StoreFinder\Domain\Repository\StaticCountryRepository
-        * @inject
-        */
-       protected $countryRepository;
-
-       /**
-        * Initialize arguments. Cant be moved to parent because of "private $argumentDefinitions = array();"
-        *
-        * @return void
-        */
-       public function initializeArguments() {
-               parent::initializeArguments();
-
-               $this->overrideArgument('options', 'object', 'Associative array with internal IDs as key, and the values are displayed in the select box', FALSE);
-               $this->overrideArgument('optionValueField', 'string', 'If specified, will call the appropriate getter on each object to determine the value.', FALSE, 'cnIso2');
-               $this->overrideArgument('optionLabelField', 'string', 'If specified, will call the appropriate getter on each object to determine the label.', FALSE, 'cnOfficialNameEn');
-               $this->overrideArgument('sortByOptionLabel', 'boolean', 'If true, List will be sorted by label.', FALSE, 'cnOfficialNameEn');
-               $this->registerArgument('allowedCountries', 'array', 'Array with countries allowed to be displayed.', FALSE, array());
-       }
-
-       /**
-        * Override the initialize method to load all available countries before rendering
-        *
-        * @return void
-        */
-       public function initialize() {
-               parent::initialize();
-
-               if (\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded('static_info_tables')) {
-                       if ($this->hasArgument('allowedCountries') && count($this->arguments['allowedCountries'])) {
-                               $this->arguments['options'] = $this->countryRepository->findByCnIso2($this->arguments['allowedCountries']);
-                       } else {
-                               $this->arguments['options'] = $this->countryRepository->findAll();
-                       }
-               }
-       }
-}
-
-?>
\ No newline at end of file
diff --git a/Classes/ViewHelpers/Format/BinaryAndViewHelper.php b/Classes/ViewHelpers/Format/BinaryAndViewHelper.php
new file mode 100644 (file)
index 0000000..bce4213
--- /dev/null
@@ -0,0 +1,42 @@
+<?php
+namespace Evoweb\StoreFinder\ViewHelpers\Format;
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2014 Sebastian Fischer <typo3@evoweb.de>
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+/**
+ * Class BinaryAndViewHelper
+ *
+ * @package Evoweb\StoreFinder\ViewHelpers\Format
+ */
+class BinaryAndViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper {
+       /**
+        * Make an binary additon and return the result
+        *
+        * @param integer $base
+        * @param integer $content
+        * @return string
+        */
+       public function render($base, $content = 0) {
+               return ($content ?: $this->renderChildren()) & $base;
+       }
+}
\ No newline at end of file
index e4340f8..0aab913 100644 (file)
@@ -23,8 +23,15 @@ namespace Evoweb\StoreFinder\ViewHelpers;
  *  This copyright notice MUST APPEAR in all copies of the script!
  ***************************************************************/
 
+/**
+ * Class MinifyViewHelper
+ *
+ * @package Evoweb\StoreFinder\ViewHelpers
+ */
 class MinifyViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper {
        /**
+        * Renders the content minified
+        *
         * @param string $content
         * @return string
         */
@@ -32,7 +39,9 @@ class MinifyViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelp
                $content = $content ? $content : $this->renderChildren();
 
                /* remove comments */
+               $content = str_replace('://', "\xff", $content);
                $content = preg_replace('@((?:\/\*(?:[^*]|(?:\*+[^*\/]))*\*+\/)|(?:\/\/.*))@', '', $content);
+               $content = str_replace("\xff", '://', $content);
 
                /* remove tabs, spaces, newlines, etc. */
                $content = str_replace(
@@ -45,6 +54,4 @@ class MinifyViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelp
 
                return $content;
        }
-}
-
-?>
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/Classes/ViewHelpers/NoopViewHelper.php b/Classes/ViewHelpers/NoopViewHelper.php
deleted file mode 100644 (file)
index e0fee87..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-<?php
-namespace Evoweb\StoreFinder\ViewHelpers;
-/***************************************************************
- *  Copyright notice
- *
- *  (c) 2013 Sebastian Fischer <typo3@evoweb.de>
- *  All rights reserved
- *
- *  This script is part of the TYPO3 project. The TYPO3 project is
- *  free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  The GNU General Public License can be found at
- *  http://www.gnu.org/copyleft/gpl.html.
- *
- *  This script is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  This copyright notice MUST APPEAR in all copies of the script!
- ***************************************************************/
-
-class NoopViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper {
-       /**
-        * @param string $content
-        * @return string
-        */
-       public function render($content = '') {
-               return $content ? $content : $this->renderChildren();
-       }
-}
-
-?>
\ No newline at end of file
index dd8c8d1..f4869d8 100644 (file)
        </meta>
        <sheets>
 
-               <sheetGeneralOptions>
+               <sheetDisplayOptions>
                        <ROOT>
                                <TCEforms>
-                                       <sheetTitle>LLL:EXT:store_finder/Resources/Private/Language/locallang_be.xml:pi_flexform.sheetGeneralOptions</sheetTitle>
+                                       <sheetTitle>LLL:EXT:store_finder/Resources/Private/Language/locallang_be.xml:pi_flexform.sheetDisplayOptions</sheetTitle>
                                        <cshFile>LLL:EXT:store_finder/Resources/Private/Language/locallang_csh.xml</cshFile>
                                </TCEforms>
                                <type>array</type>
                                <el>
-                                       <resultPageId>
+                                       <settings.showBeforeSearch>
                                                <TCEforms>
-                                                       <label>LLL:EXT:store_finder/Resources/Private/Language/locallang_be.xml:pi_flexform.resultPageId.label</label>
+                                                       <label>LLL:EXT:store_finder/Resources/Private/Language/locallang_be.xml:pi_flexform.showBeforeSearch</label>
                                                        <config>
-                                                               <type>group</type>
-                                                               <internal_type>db</internal_type>
-                                                               <allowed>pages</allowed>
-                                                               <size>1</size>
-                                                               <maxitems>1</maxitems>
-                                                               <minitems>0</minitems>
-                                                               <show_thumbs>0</show_thumbs>
+                                                               <type>check</type>
+                                                               <default>1</default>
+                                                               <items type="array">
+                                                                       <numIndex index="0" type="array">
+                                                                               <numIndex index="0">LLL:EXT:store_finder/Resources/Private/Language/locallang_be.xml:pi_flexform.showItems.search</numIndex>
+                                                                               <numIndex index="1">1</numIndex>
+                                                                       </numIndex>
+                                                                       <numIndex index="1" type="array">
+                                                                               <numIndex index="0">LLL:EXT:store_finder/Resources/Private/Language/locallang_be.xml:pi_flexform.showItems.map</numIndex>
+                                                                               <numIndex index="1">2</numIndex>
+                                                                       </numIndex>
+                                                                       <numIndex index="2" type="array">
+                                                                               <numIndex index="0">LLL:EXT:store_finder/Resources/Private/Language/locallang_be.xml:pi_flexform.showItems.list</numIndex>
+                                                                               <numIndex index="1">4</numIndex>
+                                                                       </numIndex>
+                                                               </items>
                                                        </config>
                                                </TCEforms>
-                                       </resultPageId>
+                                       </settings.showBeforeSearch>
 
-                                       <routePageId>
+                                       <settings.showAfterSearch>
                                                <TCEforms>
-                                                       <label>LLL:EXT:store_finder/Resources/Private/Language/locallang_be.xml:pi_flexform.routePageId.label</label>
+                                                       <label>LLL:EXT:store_finder/Resources/Private/Language/locallang_be.xml:pi_flexform.showAfterSearch</label>
                                                        <config>
-                                                               <type>group</type>
-                                                               <internal_type>db</internal_type>
-                                                               <allowed>pages</allowed>
-                                                               <size>1</size>
-                                                               <maxitems>1</maxitems>
-                                                               <minitems>0</minitems>
-                                                               <show_thumbs>0</show_thumbs>
-                                                       </config>
+                                                               <type>check</type>
+                                                               <default>6</default>
+                                                               <items type="array">
+                                                                       <numIndex index="0" type="array">
+                                                                               <numIndex index="0">LLL:EXT:store_finder/Resources/Private/Language/locallang_be.xml:pi_flexform.showItems.search</numIndex>
+                                                                               <numIndex index="1">1</numIndex>
+                                                                       </numIndex>
+                                                                       <numIndex index="1" type="array">
+                                                                               <numIndex index="0">LLL:EXT:store_finder/Resources/Private/Language/locallang_be.xml:pi_flexform.showItems.map</numIndex>
+                                                                               <numIndex index="1">2</numIndex>
+                                                                       </numIndex>
+                                                                       <numIndex index="2" type="array">
+                                                                               <numIndex index="0">LLL:EXT:store_finder/Resources/Private/Language/locallang_be.xml:pi_flexform.showItems.list</numIndex>
+                                                                               <numIndex index="1">4</numIndex>
+                                                                       </numIndex>
+                                                               </items>
+                                                       </config>sheetDisplayOptions
                                                </TCEforms>
-                                       </routePageId>
+                                       </settings.showAfterSearch>
 
-                                       <showStoreImage>
+                                       <settings.showStoreImage>
                                                <TCEforms>
-                                                       <label>LLL:EXT:store_finder/Resources/Private/Language/locallang_be.xml:pi_flexform.showStoreImage.label</label>
+                                                       <label>LLL:EXT:store_finder/Resources/Private/Language/locallang_be.xml:pi_flexform.showStoreImage</label>
                                                        <config>
                                                                <type>check</type>
                                                                <default>1</default>
                                                        </config>
                                                </TCEforms>
-                                       </showStoreImage>
+                                       </settings.showStoreImage>
 
-                                       <switchableControllerActions>
+                                       <settings.mapConfiguration.apiV3Layers>
                                                <TCEforms>
-                                                       <label>LLL:EXT:store_finder/Resources/Private/Language/locallang_be.xml:pi_flexform.displayMode.label</label>
+                                                       <label>LLL:EXT:store_finder/Resources/Private/Language/locallang_be.xml:pi_flexform.apiV3Layers</label>
                                                        <config>
                                                                <type>select</type>
                                                                <items type="array">
                                                                        <numIndex index="0" type="array">
-                                                                               <numIndex index="0">LLL:EXT:store_finder/Resources/Private/Language/locallang_be.xml:pi_flexform.switchableControllerActions.searchAndMapList</numIndex>
-                                                                               <numIndex index="1">Map->search;Map->mapList</numIndex>
+                                                                               <numIndex index="0">LLL:EXT:store_finder/Resources/Private/Language/locallang_be.xml:pi_flexform.apiV3Layers.trafficOverlay</numIndex>
+                                                                               <numIndex index="1">traffic</numIndex>
                                                                        </numIndex>
                                                                        <numIndex index="1" type="array">
-                                                                               <numIndex index="0">LLL:EXT:store_finder/Resources/Private/Language/locallang_be.xml:pi_flexform.switchableControllerActions.search</numIndex>
-                                                                               <numIndex index="1">Map->search</numIndex>
+                                                                               <numIndex index="0">LLL:EXT:store_finder/Resources/Private/Language/locallang_be.xml:pi_flexform.apiV3Layers.weatherOverlay</numIndex>
+                                                                               <numIndex index="1">weather</numIndex>
                                                                        </numIndex>
                                                                        <numIndex index="2" type="array">
-                                                                               <numIndex index="0">LLL:EXT:store_finder/Resources/Private/Language/locallang_be.xml:pi_flexform.switchableControllerActions.map</numIndex>
-                                                                               <numIndex index="1">Map->map</numIndex>
+                                                                               <numIndex index="0">LLL:EXT:store_finder/Resources/Private/Language/locallang_be.xml:pi_flexform.apiV3Layers.bicyclingOverlay</numIndex>
+                                                                               <numIndex index="1">bicycling</numIndex>
                                                                        </numIndex>
                                                                        <numIndex index="3" type="array">
-                                                                               <numIndex index="0">LLL:EXT:store_finder/Resources/Private/Language/locallang_be.xml:pi_flexform.switchableControllerActions.list</numIndex>
-                                                                               <numIndex index="1">Map->list</numIndex>
+                                                                               <numIndex index="0">LLL:EXT:store_finder/Resources/Private/Language/locallang_be.xml:pi_flexform.apiV3Layers.panoramioOverlay</numIndex>
+                                                                               <numIndex index="1">panoramio</numIndex>
                                                                        </numIndex>
                                                                        <numIndex index="4" type="array">
-                                                                               <numIndex index="0">LLL:EXT:store_finder/Resources/Private/Language/locallang_be.xml:pi_flexform.switchableControllerActions.mapList</numIndex>
-                                                                               <numIndex index="1">Map->mapList</numIndex>
-                                                                       </numIndex>
-                                                                       <numIndex index="5" type="array">
-                                                                               <numIndex index="0">LLL:EXT:store_finder/Resources/Private/Language/locallang_be.xml:pi_flexform.switchableControllerActions.searchMapList</numIndex>
-                                                                               <numIndex index="1">Map->searchMapList</numIndex>
+                                                                               <numIndex index="0">LLL:EXT:store_finder/Resources/Private/Language/locallang_be.xml:pi_flexform.apiV3Layers.kmlOverlay</numIndex>
+                                                                               <numIndex index="1">kml</numIndex>
                                                                        </numIndex>
                                                                </items>
+                                                               <maxitems>5</maxitems>
+                                                               <size>5</size>
+                                                       </config>
+                                               </TCEforms>
+                                       </settings.mapConfiguration.apiV3Layers>
+
+                                       <settings.allowedCountries>
+                                               <TCEforms>
+                                                       <label>LLL:EXT:store_finder/Resources/Private/Language/locallang_be.xml:pi_flexform.allowedCountries</label>
+                                                       <config>
+                                                               <type>group</type>
+                                                               <type>input</type>
+                                                               <internal_type>folder</internal_type>
+                                                               <size>1</size>
+                                                               <size>40</size>
                                                                <maxitems>1</maxitems>
-                                                               <size>6</size>
                                                        </config>
                                                </TCEforms>
-                                       </switchableControllerActions>
+                                       </settings.allowedCountries>
 
-                                       <settings.mapConfiguration.apiV3Layers>
+                                       <view.templateRootPath>
+                                               <TCEforms>
+                                                       <label>LLL:EXT:store_finder/Resources/Private/Language/locallang_be.xml:pi_flexform.templateRootPath</label>
+                                                       <config>
+                                                               <type>group</type>
+                                                               <type>input</type>
+                                                               <internal_type>folder</internal_type>
+                                                               <size>1</size>
+                                                               <size>40</size>
+                                                               <maxitems>1</maxitems>
+                                                       </config>
+                                               </TCEforms>
+                                       </view.templateRootPath>
+
+                                       <view.partialRootPath>
                                                <TCEforms>
-                                                       <label>LLL:EXT:store_finder/Resources/Private/Language/locallang_be.xml:pi_flexform.apiV3Layers.label</label>
+                                                       <label>LLL:EXT:store_finder/Resources/Private/Language/locallang_be.xml:pi_flexform.partialRootPath</label>
+                                                       <config>
+                                                               <type>group</type>
+                                                               <type>input</type>
+                                                               <internal_type>folder</internal_type>
+                                                               <size>1</size>
+                                                               <size>40</size>
+                                                               <maxitems>1</maxitems>
+                                                       </config>
+                                               </TCEforms>
+                                       </view.partialRootPath>
+                               </el>
+                       </ROOT>
+               </sheetDisplayOptions>
+
+               <sheetReferenceOptions>
+                       <ROOT>
+                               <TCEforms>
+                                       <sheetTitle>LLL:EXT:store_finder/Resources/Private/Language/locallang_be.xml:pi_flexform.sheetReferenceOptions</sheetTitle>
+                                       <cshFile>LLL:EXT:store_finder/Resources/Private/Language/locallang_csh.xml</cshFile>
+                               </TCEforms>
+                               <type>array</type>
+                               <el>
+                                       <settings.categories>
+                                               <TCEforms>
+                                                       <label>LLL:EXT:store_finder/Resources/Private/Language/locallang_be.xml:pi_flexform.categories</label>
+                                                       <config>
+                                                               <type>select</type>
+                                                               <autoSizeMax>50</autoSizeMax>
+                                                               <foreign_table>sys_category</foreign_table>
+                                                               <foreign_table_where>AND sys_category.sys_language_uid IN (-1, 0) ORDER BY sys_category.sorting ASC</foreign_table_where>
+                                                               <maxitems>9999</maxitems>
+                                                               <renderMode>tree</renderMode>
+                                                               <size>10</size>
+                                                               <treeConfig>
+                                                                       <parentField>parent</parentField>
+                                                                       <appearance>
+                                                                               <expandAll>1</expandAll>
+                                                                               <showHeader>1</showHeader>
+                                                                       </appearance>
+                                                               </treeConfig>
+                                                       </config>
+                                               </TCEforms>
+                                       </settings.categories>
+
+                                       <settings.categoryPriority>
+                                               <TCEforms>
+                                                       <label>LLL:EXT:store_finder/Resources/Private/Language/locallang_be.xml:pi_flexform.categoryPriority</label>
                                                        <config>
                                                                <type>select</type>
                                                                <items type="array">
                                                                        <numIndex index="0" type="array">
-                                                                               <numIndex index="0">LLL:EXT:store_finder/Resources/Private/Language/locallang_be.xml:pi_flexform.trafficOverlay.label</numIndex>
-                                                                               <numIndex index="1">traffic</numIndex>
+                                                                               <numIndex index="0">LLL:EXT:store_finder/Resources/Private/Language/locallang_be.xml:pi_flexform.categoryPriority.useAsFilterInFrontend</numIndex>
+                                                                               <numIndex index="1">useAsFilterInFrontend</numIndex>
                                                                        </numIndex>
                                                                        <numIndex index="1" type="array">
-                                                                               <numIndex index="0">LLL:EXT:store_finder/Resources/Private/Language/locallang_be.xml:pi_flexform.weatherOverlay.label</numIndex>
-                                                                               <numIndex index="1">weather</numIndex>
+                                                                               <numIndex index="0">LLL:EXT:store_finder/Resources/Private/Language/locallang_be.xml:pi_flexform.categoryPriority.useParentIfNoFilterSelected</numIndex>
+                                                                               <numIndex index="1">useParentIfNoFilterSelected</numIndex>
                                                                        </numIndex>
                                                                        <numIndex index="2" type="array">
-                                                                               <numIndex index="0">LLL:EXT:store_finder/Resources/Private/Language/locallang_be.xml:pi_flexform.bicyclingOverlay.label</numIndex>
-                                                                               <numIndex index="1">bicycling</numIndex>
-                                                                       </numIndex>
-                                                                       <numIndex index="3" type="array">
-                                                                               <numIndex index="0">LLL:EXT:store_finder/Resources/Private/Language/locallang_be.xml:pi_flexform.panoramioOverlay.label</numIndex>
-                                                                               <numIndex index="1">panoramio</numIndex>
-                                                                       </numIndex>
-                                                                       <numIndex index="4" type="array">
-                                                                               <numIndex index="0">LLL:EXT:store_finder/Resources/Private/Language/locallang_be.xml:pi_flexform.kmlOverlay.label</numIndex>
-                                                                               <numIndex index="1">kml</numIndex>
+                                                                               <numIndex index="0">LLL:EXT:store_finder/Resources/Private/Language/locallang_be.xml:pi_flexform.categoryPriority.limitResultsToCategories</numIndex>
+                                                                               <numIndex index="1">limitResultsToCategories</numIndex>
                                                                        </numIndex>
                                                                </items>
-                                                               <maxitems>5</maxitems>
-                                                               <size>5</size>
                                                        </config>
                                                </TCEforms>
-                                       </settings.mapConfiguration.apiV3Layers>
+                                       </settings.categoryPriority>
+
+                                       <settings.resultPageId>
+                                               <TCEforms>
+                                                       <label>LLL:EXT:store_finder/Resources/Private/Language/locallang_be.xml:pi_flexform.resultPageId</label>
+                                                       <config>
+                                                               <type>group</type>
+                                                               <internal_type>db</internal_type>
+                                                               <allowed>pages</allowed>
+                                                               <size>1</size>
+                                                               <maxitems>1</maxitems>
+                                                               <minitems>0</minitems>
+                                                               <show_thumbs>0</show_thumbs>
+                                                       </config>
+                                               </TCEforms>
+                                       </settings.resultPageId>
+
+                                       <settings.routePageId>
+                                               <TCEforms>
+                                                       <label>LLL:EXT:store_finder/Resources/Private/Language/locallang_be.xml:pi_flexform.routePageId</label>
+                                                       <config>
+                                                               <type>group</type>
+                                                               <internal_type>db</internal_type>
+                                                               <allowed>pages</allowed>
+                                                               <size>1</size>
+                                                               <maxitems>1</maxitems>
+                                                               <minitems>0</minitems>
+                                                               <show_thumbs>0</show_thumbs>
+                                                       </config>
+                                               </TCEforms>
+                                       </settings.routePageId>
+
+                                       <settings.singleLocationId>
+                                               <TCEforms>
+                                                       <label>LLL:EXT:store_finder/Resources/Private/Language/locallang_be.xml:pi_flexform.singleLocationId</label>
+                                                       <config>
+                                                               <type>group</type>
+                                                               <internal_type>db</internal_type>
+                                                               <allowed>tx_storefinder_domain_model_location</allowed>
+                                                               <size>1</size>
+                                                               <maxitems>1</maxitems>
+                                                               <minitems>0</minitems>
+                                                               <show_thumbs>0</show_thumbs>
+                                                       </config>
+                                               </TCEforms>
+                                       </settings.singleLocationId>
                                </el>
                        </ROOT>
-               </sheetGeneralOptions>
+               </sheetReferenceOptions>
        </sheets>
 </T3DataStructure>
\ No newline at end of file
index 31732de..144fdd0 100644 (file)
@@ -4,7 +4,7 @@ mod.wizards {
                        plugins {
                                elements {
                                        storefinder_map {
-                                               icon = ../typo3conf/ext/store_finder/Resources/Public/Icons/ce_wiz.gif
+                                               icon = ../typo3conf/ext/store_finder/Resources/Public/Icons/google-maps-icon.png
                                                title = LLL:EXT:store_finder/Resources/Private/Language/locallang_be.xml:pi1_title
                                                description = LLL:EXT:store_finder/Resources/Private/Language/locallang_be.xml:pi1_plus_wiz_description
                                                tt_content_defValues {
diff --git a/Configuration/TCA/tx_storefinder_domain_model_attribute.php b/Configuration/TCA/tx_storefinder_domain_model_attribute.php
new file mode 100644 (file)
index 0000000..5c48c2a
--- /dev/null
@@ -0,0 +1,98 @@
+<?php
+return array(
+       'ctrl' => array(
+               'title' => 'LLL:EXT:store_finder/Resources/Private/Language/locallang_db.xml:tx_storefinder_domain_model_attribute',
+               'label' => 'name',
+               'label_alt' => 'icon',
+               'label_alt_force' => '1',
+               'tstamp' => 'tstamp',
+               'crdate' => 'crdate',
+               'cruser_id' => 'cruser_id',
+               'sortby' => 'sorting',
+               'delete' => 'deleted',
+
+               'type' => 'type',
+               'languageField' => 'sys_language_uid',
+               'transOrigPointerField' => 'l10n_parent',
+               'transOrigDiffSourceField' => 'l10n_diffsource',
+
+               'selicon_field' => 'icon',
+               'selicon_field_path' => 'uploads/tx_storefinder',
+
+               'enablecolumns' => array(
+                       'disabled' => 'hidden',
+               ),
+               'iconfile' => '../typo3conf/ext/store_finder/Resources/Public/Icons/tx_storefinder_domain_model_attribute.gif',
+       ),
+
+       'interface' => array(
+               'showRecordFieldList' => 'sys_language_uid,l10n_parent,l10n_diffsource,name,icon'
+       ),
+
+       'columns' => array(
+               'sys_language_uid' => array(
+                       'exclude' => 1,
+                       'label' => 'LLL:EXT:lang/locallang_general.xml:LGL.language',
+                       'config' => array(
+                               'type' => 'select',
+                               'foreign_table' => 'sys_language',
+                               'foreign_table_where' => 'ORDER BY sys_language.title',
+                               'items' => array(
+                                       array('LLL:EXT:lang/locallang_general.xml:LGL.allLanguages', -1),
+                                       array('LLL:EXT:lang/locallang_general.xml:LGL.default_value', 0)
+                               )
+                       )
+               ),
+               'l10n_parent' => array(
+                       'displayCond' => 'FIELD:sys_language_uid:>:0',
+                       'exclude' => 1,
+                       'label' => 'LLL:EXT:lang/locallang_general.xml:LGL.l18n_parent',
+                       'config' => array(
+                               'type' => 'select',
+                               'items' => array(
+                                       array('', 0),
+                               ),
+                               'foreign_table' => 'tx_storefinder_domain_model_attribute',
+                               'foreign_table_where' => 'AND tx_storefinder_domain_model_attribute.pid=###CURRENT_PID### AND tx_storefinder_domain_model_attribute.sys_language_uid IN (-1,0)',
+                       )
+               ),
+               'l10n_diffsource' => array(
+                       'config' => array(
+                               'type' => 'passthrough'
+                       )
+               ),
+               'name' => array(
+                       'exclude' => 0,
+                       'label' => 'LLL:EXT:store_finder/Resources/Private/Language/locallang_db.xml:tx_storefinder_domain_model_attribute.name',
+                       'config' => array(
+                               'type' => 'input',
+                               'size' => '30',
+                               'eval' => 'required,trim',
+                       )
+               ),
+
+               'icon' => array(
+                       'exclude' => 0,
+                       'label' => 'LLL:EXT:store_finder/Resources/Private/Language/locallang_db.xml:tx_storefinder_domain_model_attribute.icon',
+                       'config' => array(
+                               'type' => 'group',
+                               'internal_type' => 'file',
+                               'allowed' => 'gif,png,jpeg,jpg',
+                               'max_size' => 500,
+                               'uploadfolder' => 'uploads/tx_storefinder',
+                               'show_thumbs' => 1,
+                               'size' => 1,
+                               'minitems' => 0,
+                               'maxitems' => 1,
+                       )
+               ),
+       ),
+
+       'types' => array(
+               '0' => array('showitem' => 'sys_language_uid;;;;1-1-1, l10n_parent, l10n_diffsource, name, icon')
+       ),
+
+       'palettes' => array(
+               '1' => array('showitem' => '')
+       )
+);
\ No newline at end of file
diff --git a/Configuration/TCA/tx_storefinder_domain_model_location.php b/Configuration/TCA/tx_storefinder_domain_model_location.php
new file mode 100644 (file)
index 0000000..8f0c5d6
--- /dev/null
@@ -0,0 +1,451 @@
+<?php
+return array(
+       'ctrl' => array(
+               'title' => 'LLL:EXT:store_finder/Resources/Private/Language/locallang_db.xml:tx_storefinder_domain_model_location',
+               'label' => 'name',
+               'tstamp' => 'tstamp',
+               'crdate' => 'crdate',
+               'cruser_id' => 'cruser_id',
+               'sortby' => 'sorting',
+               'delete' => 'deleted',
+
+               'languageField' => 'sys_language_uid',
+               'transOrigPointerField' => 'l10n_parent',
+               'transOrigDiffSourceField' => 'l10n_diffsource',
+
+               'requestUpdate' => 'country',
+               'searchFields' => 'name, zipcode, city, address, country, notes',
+               'enablecolumns' => array(
+                       'disabled' => 'hidden',
+                       'starttime' => 'starttime',
+                       'endtime' => 'endtime',
+                       'fe_group' => 'fe_group',
+               ),
+               'dividers2tabs' => 1,
+               'iconfile' => '../typo3conf/ext/store_finder/Resources/Public/Icons/tx_storefinder_domain_model_location.gif',
+       ),
+
+       'interface' => array(
+               'showRecordFieldList' => 'hidden,endtime,fe_group,name,storeid,address,additionaladdress,person,city,state,zipcode,country,attributes,products,phone,mobile,hours,url,notes,image,icon,content,use_coordinate,categories,latitude,longitude,geocode'
+       ),
+
+       'columns' => array(
+               'hidden' => $GLOBALS['TCA']['tt_content']['columns']['hidden'],
+               'starttime' => $GLOBALS['TCA']['tt_content']['columns']['starttime'],
+               'endtime' => $GLOBALS['TCA']['tt_content']['columns']['endtime'],
+               'fe_group' => $GLOBALS['TCA']['tt_content']['columns']['fe_group'],
+               'sys_language_uid' => $GLOBALS['TCA']['tt_content']['columns']['sys_language_uid'],
+
+               'l18n_parent' => array(
+                       'displayCond' => 'FIELD:sys_language_uid:>:0',
+                       'exclude' => 1,
+                       'label' => 'LLL:EXT:lang/locallang_general.xlf:LGL.l18n_parent',
+                       'config' => array(
+                               'type' => 'select',
+                               'items' => array(
+                                       array(
+                                               '',
+                                               0
+                                       )
+                               ),
+                               'foreign_table' => 'tx_storefinder_domain_model_location',
+                               'foreign_table_where' => 'AND tx_storefinder_domain_model_location.pid=###CURRENT_PID### AND tx_storefinder_domain_model_location.sys_language_uid IN (-1,0)'
+                       )
+               ),
+
+                       // address
+               'name' => array(
+                       'exclude' => 0,
+                       'label' => 'LLL:EXT:store_finder/Resources/Private/Language/locallang_db.xml:tx_storefinder_domain_model_location.name',
+                       'config' => array(
+                               'type' => 'input',
+                               'size' => '30',
+                               'max' => '256',
+                               'eval' => 'required,trim',
+                       )
+               ),
+
+               'storeid' => array(
+                       'exclude' => 0,
+                       'label' => 'LLL:EXT:store_finder/Resources/Private/Language/locallang_db.xml:tx_storefinder_domain_model_location.storeid',
+                       'config' => array(
+                               'type' => 'input',
+                               'size' => '30',
+                               'eval' => 'trim',
+                       )
+               ),
+
+               'address' => array(
+                       'exclude' => 0,
+                       'label' => 'LLL:EXT:store_finder/Resources/Private/Language/locallang_db.xml:tx_storefinder_domain_model_location.address',
+                       'config' => array(
+                               'type' => 'text',
+                               'cols' => '30',
+                               'rows' => '3',
+                               'eval' => 'trim',
+                       )
+               ),
+
+               'additionaladdress' => array(
+                       'exclude' => 0,
+                       'label' => 'LLL:EXT:store_finder/Resources/Private/Language/locallang_db.xml:tx_storefinder_domain_model_location.additionaladdress',
+                       'config' => array(
+                               'type' => 'input',
+                               'size' => '30',
+                               'eval' => 'trim',
+                       )
+               ),
+
+               'zipcode' => array(
+                       'exclude' => 0,
+                       'label' => 'LLL:EXT:store_finder/Resources/Private/Language/locallang_db.xml:tx_storefinder_domain_model_location.zipcode',
+                       'config' => array(
+                               'type' => 'input',
+                               'size' => '30',
+                               'eval' => 'required,trim',
+                       )
+               ),
+
+               'city' => array(
+                       'exclude' => 0,
+                       'label' => 'LLL:EXT:store_finder/Resources/Private/Language/locallang_db.xml:tx_storefinder_domain_model_location.city',
+                       'config' => array(
+                               'type' => 'input',
+                               'size' => '30',
+                               'eval' => 'required,trim',
+                       )
+               ),
+
+               'state' => array(
+                       'exclude' => 0,
+                       'label' => 'LLL:EXT:store_finder/Resources/Private/Language/locallang_db.xml:tx_storefinder_domain_model_location.state',
+                       'displayCond' => 'FIELD:country:>:0',
+                       'config' => array(
+                               'type' => 'select',
+                               'items' => array(
+                                       array('', 0),
+                               ),
+                               'foreign_table' => 'static_country_zones',
+                               'foreign_table_where' => 'AND zn_country_uid = ###REC_FIELD_country### ORDER BY static_country_zones.zn_name_local',
+                               'size' => 1,
+                               'minitems' => 0,
+                               'maxitems' => 1
+                       )
+               ),
+
+               'country' => array(
+                       'exclude' => 0,
+                       'label' => 'LLL:EXT:store_finder/Resources/Private/Language/locallang_db.xml:tx_storefinder_domain_model_location.country',
+                       'config' => array(
+                               'type' => 'select',
+                               'items' => array(
+                                       array('', 0),
+                               ),
+                               'foreign_table' => 'static_countries',
+                               'itemsProcFunc' => 'SJBR\\StaticInfoTables\\Hook\\Backend\\Form\\ElementRenderingHelper->translateCountriesSelector',
+                               'size' => 1,
+                               'minitems' => 1,
+                               'maxitems' => 1
+                       )
+               ),
+
+                       // contact
+               'person' => array(
+                       'exclude' => 0,
+                       'label' => 'LLL:EXT:store_finder/Resources/Private/Language/locallang_db.xml:tx_storefinder_domain_model_location.person',
+                       'config' => array(
+                               'type' => 'input',
+                               'size' => '30',
+                               'eval' => 'trim',
+                       )
+               ),
+
+               'phone' => array(
+                       'exclude' => 0,
+                       'label' => 'LLL:EXT:store_finder/Resources/Private/Language/locallang_db.xml:tx_storefinder_domain_model_location.phone',
+                       'config' => array(
+                               'type' => 'input',
+                               'size' => '30',
+                               'eval' => 'trim',
+                       )
+               ),
+
+               'mobile' => array(
+                       'exclude' => 0,
+                       'label' => 'LLL:EXT:store_finder/Resources/Private/Language/locallang_db.xml:tx_storefinder_domain_model_location.mobile',
+                       'config' => array(
+                               'type' => 'input',
+                               'size' => '30',
+                               'eval' => 'trim',
+                       )
+               ),
+
+               'fax' => array(
+                       'exclude' => 0,
+                       'label' => 'LLL:EXT:store_finder/Resources/Private/Language/locallang_db.xml:tx_storefinder_domain_model_location.fax',
+                       'config' => array(
+                               'type' => 'input',
+                               'size' => '30',
+                               'eval' => 'trim',
+                       )
+               ),
+
+               'email' => array(
+                       'exclude' => 0,
+                       'label' => 'LLL:EXT:store_finder/Resources/Private/Language/locallang_db.xml:tx_storefinder_domain_model_location.email',
+                       'config' => array(
+                               'type' => 'input',
+                               'size' => '30',
+                               'eval' => 'trim',
+                       )
+               ),
+
+               'hours' => array(
+                       'exclude' => 0,
+                       'label' => 'LLL:EXT:store_finder/Resources/Private/Language/locallang_db.xml:tx_storefinder_domain_model_location.hours',
+                       'config' => array(
+                               'type' => 'text',
+                               'cols' => '30',
+                               'rows' => '5',
+                       )
+               ),
+
+
+                       // relations
+               'related' => array(
+                       'exclude' => 0,
+                       'label' => 'LLL:EXT:store_finder/Resources/Private/Language/locallang_db.xml:tx_storefinder_domain_model_location.related',
+                       'config' => array(
+                               'type' => 'select',
+                               'items' => array(
+                                       Array('', 0)
+                               ),
+                               'foreign_table' => 'tx_storefinder_domain_model_location',
+                               'foreign_table_where' => 'AND tx_storefinder_domain_model_location.uid != ###THIS_UID### ORDER BY tx_storefinder_domain_model_location.name',
+                               'MM' => 'sys_category_record_mm',
+                               'MM_match_fields' => array(
+                                       'tablenames' => 'tx_storefinder_domain_model_location',
+                                       'fieldname' => 'related',
+                               ),
+                               'minitems' => '0',
+                               'maxitems' => '1',
+                               'default' => '0',
+                       )
+               ),
+
+               'categories' => array(
+                       'label' => 'LLL:EXT:store_finder/Resources/Private/Language/locallang_db.xml:tx_storefinder_domain_model_location.categories',
+                       'config' => array(
+                               'type' => 'select',
+                               'foreign_table' => 'sys_category',
+                               'foreign_table_where' => 'AND sys_category.sys_language_uid IN (0,-1) ORDER BY sys_category.title ASC',
+                               'MM' => 'sys_category_record_mm',
+                               'MM_opposite_field' => 'items',
+                               'MM_match_fields' => array(
+                                       'tablenames' => 'tx_storefinder_domain_model_location',
+                                       'fieldname' => 'categories',
+                               ),
+                               'size' => 10,
+                               'autoSizeMax' => 50,
+                               'maxitems' => 9999,
+                               'renderMode' => 'tree',
+                               'treeConfig' => array(
+                                       'parentField' => 'parent',
+                                       'appearance' => array(
+                                               'expandAll' => TRUE,
+                                               'showHeader' => TRUE,
+                                       ),
+                               ),
+                               'wizards' => array(
+                                       'add' => array(
+                                               'type' => 'script',
+                                               'title' => 'LLL:EXT:store_finder/Resources/Private/Language/locallang_db.xml:sys_category.add',
+                                               'icon' => 'add.gif',
+                                               'params' => array(
+                                                       'table' => 'sys_category',
+                                                       'pid' => '###CURRENT_PID###',
+                                                       'setValue' => 'prepend'
+                                               ),
+                                               'script' => 'wizard_add.php',
+                                       )
+                               ),
+                       )
+               ),
+
+               'attributes' => array(
+                       'exclude' => 1,
+                       'label' => 'LLL:EXT:store_finder/Resources/Private/Language/locallang_db.xml:tx_storefinder_domain_model_location.attributes',
+                       'config' => array(
+                               'type' => 'select',
+                               'foreign_table' => 'tx_storefinder_domain_model_attribute',
+                               'foreign_table_where' => ' AND tx_storefinder_domain_model_attribute.sys_language_uid = 0 AND tx_storefinder_domain_model_attribute.pid = ###CURRENT_PID###',
+                               'MM' => 'tx_storefinder_location_attribute_mm',
+                               'MM_match_fields' => array(
+                                       'tablenames' => 'tx_storefinder_domain_model_attribute',
+                                       'fieldname' => 'attributes',
+                               ),
+                               'size' => 10,
+                               'maxitems' => 30,
+                       )
+               ),
+
+               'icon' => array(
+                       'exclude' => 0,
+                       'label' => 'LLL:EXT:store_finder/Resources/Private/Language/locallang_db.xml:tx_storefinder_domain_model_location.icon',
+                       'config' => array(
+                               'type' => 'select',
+                               'items' => array(),
+                               'size' => 1,
+                               'maxitems' => 1,
+                       )
+               ),
+
+               'latitude' => array(
+                       'exclude' => 0,
+                       'label' => 'LLL:EXT:store_finder/Resources/Private/Language/locallang_db.xml:tx_storefinder_domain_model_location.latitude',
+                       'config' => array(
+                               'type' => 'input',
+                               'readOnly' => 1,
+                               'size' => 10,
+                       )
+               ),
+
+               'longitude' => array(
+                       'exclude' => 0,
+                       'label' => 'LLL:EXT:store_finder/Resources/Private/Language/locallang_db.xml:tx_storefinder_domain_model_location.longitude',
+                       'config' => array(
+                               'type' => 'input',
+                               'readOnly' => 1,
+                               'size' => 10,
+                       )
+               ),
+
+               'center' => array(
+                       'exclude' => 1,
+                       'label' => 'LLL:EXT:store_finder/Resources/Private/Language/locallang_db.xml:tx_storefinder_domain_model_location.center',
+                       'config' => array(
+                               'type' => 'check',
+                       )
+               ),
+
+               'distance' => array(
+                       'exclude' => 0,
+                       'label' => 'LLL:EXT:store_finder/Resources/Private/Language/locallang_db.xml:tx_storefinder_domain_model_location.distance',
+                       'config' => array(
+                               'type' => 'input',
+                               'readOnly' => 1,
+                               'size' => 10,
+                       )
+               ),
+
+
+                       // informations
+               'products' => array(
+                       'exclude' => 0,
+                       'label' => 'LLL:EXT:store_finder/Resources/Private/Language/locallang_db.xml:tx_storefinder_domain_model_location.products',
+                       'config' => array(
+                               'type' => 'input',
+                               'size' => '50',
+                               'eval' => 'trim',
+                               'max' => '255',
+                       )
+               ),
+
+               'notes' => array(
+                       'exclude' => 0,
+                       'label' => 'LLL:EXT:store_finder/Resources/Private/Language/locallang_db.xml:tx_storefinder_domain_model_location.notes',
+                       'config' => array(
+                               'type' => 'text',
+                               'cols' => '80',
+                               'rows' => '15',
+                               'softref' => 'rtehtmlarea_images,typolink_tag,images,email[subst],url',
+                       )
+               ),
+
+               'url' => array(
+                       'exclude' => 0,
+                       'label' => 'LLL:EXT:store_finder/Resources/Private/Language/locallang_db.xml:tx_storefinder_domain_model_location.url',
+                       'config' => array(
+                               'type' => 'input',
+                               'size' => '30',
+                               'max' => '255',
+                               'eval' => 'trim',
+                               'wizards' => Array(
+                                       '_PADDING' => 2,
+                                       'link' => Array(
+                                               'type' => 'popup',
+                                               'title' => 'Link',
+                                               'icon' => 'link_popup.gif',
+                                               'script' => 'browse_links.php?mode=wizard',
+                                               'JSopenParams' => 'height=300,width=500,status=0,menubar=0,scrollbars=1'
+                                       )
+                               )
+                       )
+               ),
+
+               'image' => $GLOBALS['TCA']['tt_content']['columns']['image'],
+               'media' => $GLOBALS['TCA']['tt_content']['columns']['media'],
+
+               'content' => array(
+                       'exclude' => 1,
+                       'label' => 'LLL:EXT:store_finder/Resources/Private/Language/locallang_db.xml:tx_storefinder_domain_model_location.content',
+                       'config' => array(
+                               'type' => 'inline',
+                               'allowed' => 'tt_content',
+                               'foreign_table' => 'tt_content',
+                               'minitems' => 0,
+                               'maxitems' => 10,
+                               'appearance' => array(
+                                       'collapseAll' => 1,
+                                       'expandSingle' => 1,
+                                       'levelLinksPosition' => 'bottom',
+                                       'useSortable' => 1,
+                                       'showPossibleLocalizationRecords' => 1,
+                                       'showRemovedLocalizationRecords' => 1,
+                                       'showAllLocalizationLink' => 1,
+                                       'showSynchronizationLink' => 1,
+                                       'enabledControls' => array(
+                                               'info' => FALSE,
+                                       )
+                               )
+                       )
+               ),
+       ),
+
+       'types' => array(
+               '0' => array('showitem' => '
+                       --div--;LLL:EXT:store_finder/Resources/Private/Language/locallang_db.xml:div-address,
+                               name, storeid, address, additionaladdress, zipcode, city, state, country,
+                       --div--;LLL:EXT:store_finder/Resources/Private/Language/locallang_db.xml:div-contact,
+                               person, phone, mobile, fax, email, hours,
+                       --div--;LLL:EXT:store_finder/Resources/Private/Language/locallang_db.xml:div-relations,
+                               related, categories, attributes, icon,
+                               --palette--;LLL:EXT:store_finder/Resources/Private/Language/locallang_db.xml:palette-coordinates;coordinates,
+                       --div--;LLL:EXT:store_finder/Resources/Private/Language/locallang_db.xml:div-informations,
+                               products, notes;;;richtext:rte_transform[flag=rte_enabled|mode=ts_css], url,
+                               image;LLL:EXT:store_finder/Resources/Private/Language/locallang_db.xml:tx_storefinder_domain_model_location.image,
+                               media;LLL:EXT:store_finder/Resources/Private/Language/locallang_db.xml:tx_storefinder_domain_model_location.media, content,
+                       --div--;LLL:EXT:cms/locallang_ttc.xlf:tabs.access,
+                               --palette--;LLL:EXT:cms/locallang_ttc.xlf:palette.visibility;visibility,
+                               --palette--;LLL:EXT:cms/locallang_ttc.xlf:palette.access;access,')
+       ),
+
+       'palettes' => array(
+               'coordinates' => array(
+                       'showitem' => 'latitude, longitude, center',
+                       'canNotCollapse' => 1
+               ),
+               'visibility' => array(
+                       'showitem' => '
+                               hidden;LLL:EXT:store_finder/Resources/Private/Language/locallang_db.xml:tx_storefinder_domain_model_location.hidden',
+                       'canNotCollapse' => 1
+               ),
+               'access' => array(
+                       'showitem' => '
+                               starttime;LLL:EXT:cms/locallang_ttc.xlf:starttime_formlabel,
+                               endtime;LLL:EXT:cms/locallang_ttc.xlf:endtime_formlabel,
+                               --linebreak--, fe_group;LLL:EXT:cms/locallang_ttc.xlf:fe_group_formlabel',
+                       'canNotCollapse' => 1
+               ),
+       )
+);
diff --git a/Configuration/Tca/tx_storefinder_domain_model_attribute.php b/Configuration/Tca/tx_storefinder_domain_model_attribute.php
deleted file mode 100644 (file)
index 6d20fe0..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-<?php
-
-if (!defined('TYPO3_MODE')) {
-       die('Access denied.');
-}
-
-$GLOBALS['TCA']['tx_storefinder_domain_model_attribute'] = array(
-       'ctrl' => $GLOBALS['TCA']['tx_storefinder_domain_model_attribute']['ctrl'],
-       'interface' => array(
-               'showRecordFieldList' => 'sys_language_uid,l10n_parent,l10n_diffsource,name,icon'
-       ),
-       'feInterface' => $GLOBALS['TCA']['tx_storefinder_domain_model_attribute']['feInterface'],
-       'columns' => array(
-               'sys_language_uid' => array(
-                       'exclude' => 1,
-                       'label' => 'LLL:EXT:lang/locallang_general.xml:LGL.language',
-                       'config' => array(
-                               'type' => 'select',
-                               'foreign_table' => 'sys_language',
-                               'foreign_table_where' => 'ORDER BY sys_language.title',
-                               'items' => array(
-                                       array('LLL:EXT:lang/locallang_general.xml:LGL.allLanguages', -1),
-                                       array('LLL:EXT:lang/locallang_general.xml:LGL.default_value', 0)
-                               )
-                       )
-               ),
-               'l10n_parent' => array(
-                       'displayCond' => 'FIELD:sys_language_uid:>:0',
-                       'exclude' => 1,
-                       'label' => 'LLL:EXT:lang/locallang_general.xml:LGL.l18n_parent',
-                       'config' => array(
-                               'type' => 'select',
-                               'items' => array(
-                                       array('', 0),
-                               ),
-                               'foreign_table' => 'tx_storefinder_domain_model_attribute',
-                               'foreign_table_where' => 'AND tx_storefinder_domain_model_attribute.pid=###CURRENT_PID### AND tx_storefinder_domain_model_attribute.sys_language_uid IN (-1,0)',
-                       )
-               ),
-               'l10n_diffsource' => array(
-                       'config' => array(
-                               'type' => 'passthrough'
-                       )
-               ),
-               'name' => array(
-                       'exclude' => 0,
-                       'label' => STOREFINDERLLFILE . 'tx_storefinder_domain_model_attribute.name',
-                       'config' => array(
-                               'type' => 'input',
-                               'size' => '30',
-                               'eval' => 'required,trim',
-                       )
-               ),
-
-               'icon' => array(
-                       'exclude' => 0,
-                       'label' => STOREFINDERLLFILE . 'tx_storefinder_domain_model_attribute.icon',
-                       'config' => array(
-                               'type' => 'group',
-                               'internal_type' => 'file',
-                               'allowed' => 'gif,png,jpeg,jpg',
-                               'max_size' => 500,
-                               'uploadfolder' => 'uploads/tx_storefinder',
-                               'show_thumbs' => 1,
-                               'size' => 1,
-                               'minitems' => 0,
-                               'maxitems' => 1,
-                       )
-               ),
-       ),
-       'types' => array(
-               '0' => array('showitem' => 'sys_language_uid;;;;1-1-1, l10n_parent, l10n_diffsource, name, icon')
-       ),
-       'palettes' => array(
-               '1' => array('showitem' => '')
-       )
-);
-
-?>
\ No newline at end of file
diff --git a/Configuration/Tca/tx_storefinder_domain_model_location.php b/Configuration/Tca/tx_storefinder_domain_model_location.php
deleted file mode 100644 (file)
index 687373e..0000000
+++ /dev/null
@@ -1,453 +0,0 @@
-<?php
-
-if (!defined('TYPO3_MODE')) {
-       die('Access denied.');
-}
-
-$GLOBALS['TCA']['tx_storefinder_domain_model_location'] = array(
-       'ctrl' => $GLOBALS['TCA']['tx_storefinder_domain_model_location']['ctrl'],
-       'interface' => array(
-               'showRecordFieldList' => 'hidden,endtime,fe_group,name,storeid,address,additionaladdress,person,city,state,zipcode,country,attributes,products,phone,mobile,hours,url,notes,image,icon,content,use_coordinate,categories,latitude,longitude,geocode'
-       ),
-       'feInterface' => $GLOBALS['TCA']['tx_storefinder_domain_model_location']['feInterface'],
-       'columns' => array(
-               'hidden' => array(
-                       'exclude' => 1,
-                       'label' => 'LLL:EXT:lang/locallang_general.xml:LGL.hidden',
-                       'config' => array(
-                               'type' => 'check',
-                               'items' => array ('1' => array('0' => 'LLL:EXT:cms/locallang_ttc.xml:hidden.I.0', ), ),
-                       ),
-               ),
-               'starttime' => array(
-                       'exclude' => 1,
-                       'label' => 'LLL:EXT:lang/locallang_general.xml:LGL.starttime',
-                       'config' => array(
-                               'type' => 'input',
-                               'size' => '13',
-                               'max' => '20',
-                               'eval' => 'date',
-                               'default' => '0',
-                       ),
-               ),
-               'endtime' => array(
-                       'exclude' => 1,
-                       'label' => 'LLL:EXT:lang/locallang_general.xml:LGL.endtime',
-                       'config' => array(
-                               'type' => 'input',
-                               'size' => '13',
-                               'max' => '20',
-                               'eval' => 'date',
-                               'default' => '0',
-                               'range' => array(
-                                       'upper' => mktime(0, 0, 0, 12, 31, 2020),
-                               ),
-                       ),
-               ),
-               'fe_group' => array(
-                       'exclude' => 1,
-                       'label' => 'LLL:EXT:lang/locallang_general.xml:LGL.fe_group',
-                       'config' => array(
-                               'type' => 'select',
-                               'size' => 5,
-                               'maxitems' => 20,
-                               'items' => array(
-                                       array('LLL:EXT:lang/locallang_general.xml:LGL.hide_at_login', -1,),
-                                       array('LLL:EXT:lang/locallang_general.xml:LGL.any_login', -2,),
-                                       array('LLL:EXT:lang/locallang_general.xml:LGL.usergroups', '--div--',),
-                               ),
-                               'exclusiveKeys' => '-1,-2',
-                               'foreign_table' => 'fe_groups',
-                               'foreign_table_where' => 'ORDER BY fe_groups.title',
-                       ),
-               ),
-
-               'name' => array(
-                       'exclude' => 0,
-                       'label' => STOREFINDERLLFILE . 'tx_storefinder_domain_model_location.name',
-                       'config' => array(
-                               'type' => 'input',
-                               'size' => '30',
-                               'eval' => 'required,trim',
-                       )
-               ),
-
-               'related' => array(
-                       'exclude' => 0,
-                       'label' => STOREFINDERLLFILE . 'tx_storefinder_domain_model_location.related',
-                       'config' => array(
-                               'type' => 'select',
-                               'items' => array(
-                                       Array('', 0)
-                               ),
-                               'foreign_table' => 'tx_storefinder_domain_model_location',
-                               'foreign_table_where' => 'AND tx_storefinder_domain_model_location.uid != ###THIS_UID###',
-                               'minitems' => '0',
-                               'maxitems' => '1',
-                               'default' => '0',
-                       )
-               ),
-
-               'storeid' => array(
-                       'exclude' => 0,
-                       'label' => STOREFINDERLLFILE . 'tx_storefinder_domain_model_location.storeid',
-                       'config' => array(
-                               'type' => 'input',
-                               'size' => '30',
-                               'eval' => 'trim',
-                       )
-               ),
-
-               'attributes' => array(
-                       'exclude' => 1,
-                       'label' => STOREFINDERLLFILE . 'tx_storefinder_domain_model_location.attributes',
-                       'config' => array(
-                               'type' => 'select',
-                               'foreign_table' => 'tx_storefinder_domain_model_attribute',
-                               'foreign_table_loadIcon' => 1,
-                               'iconsInOptionTags' => 1,
-                               'size' => 10,
-                               'maxitems' => 30,
-                               'show_thumbs' => 1,
-                       )
-               ),
-
-               'address' => array(
-                       'exclude' => 0,
-                       'label' => STOREFINDERLLFILE . 'tx_storefinder_domain_model_location.address',
-                       'config' => array(
-                               'type' => 'input',
-                               'size' => '30',
-                               'eval' => 'trim',
-                       )
-               ),
-
-               'additionaladdress' => array(
-                       'exclude' => 0,
-                       'label' => STOREFINDERLLFILE . 'tx_storefinder_domain_model_location.additionaladdress',
-                       'config' => array(
-                               'type' => 'input',
-                               'size' => '30',
-                               'eval' => 'trim',
-                       )
-               ),
-
-               'person' => array(
-                       'exclude' => 0,
-                       'label' => STOREFINDERLLFILE . 'tx_storefinder_domain_model_location.person',
-                       'config' => array(
-                               'type' => 'input',
-                               'size' => '30',
-                               'eval' => 'trim',
-                       )
-               ),
-
-               'city' => array(
-                       'exclude' => 0,
-                       'label' => STOREFINDERLLFILE . 'tx_storefinder_domain_model_location.city',
-                       'config' => array(
-                               'type' => 'input',
-                               'size' => '30',
-                               'eval' => 'required,trim',
-                       )
-               ),
-
-               'zipcode' => array(
-                       'exclude' => 0,
-                       'label' => STOREFINDERLLFILE . 'tx_storefinder_domain_model_location.zipcode',
-                       'config' => array(
-                               'type' => 'input',
-                               'size' => '30',
-                               'eval' => 'required,trim',
-                       )
-               ),
-
-               'state' => array(
-                       'exclude' => 0,
-                       'label' => STOREFINDERLLFILE . 'tx_storefinder_domain_model_location.state',
-                       'displayCond' => 'FIELD:country:>:0',
-                       'config' => array(
-                               'type' => 'select',
-                               'items' => array(
-                                       array('', 0),
-                               ),
-                               'foreign_table' => 'static_country_zones',
-                               'foreign_table_where' => 'AND zn_country_uid = ###REC_FIELD_country### ORDER BY static_country_zones.zn_name_local',
-                               'size' => 1,
-                               'minitems' => 0,
-                               'maxitems' => 1
-                       )
-               ),
-
-               'country' => array(
-                       'exclude' => 0,
-                       'label' => STOREFINDERLLFILE . 'tx_storefinder_domain_model_location.country',
-                       'config' => array(
-                               'type' => 'select',
-                               'items' => array(
-                                       array('', 0),
-                               ),
-                               'foreign_table' => 'static_countries',
-                               'itemsProcFunc' => 'SJBR\\StaticInfoTables\\Hook\\Backend\\Form\\ElementRenderingHelper->translateCountriesSelector',
-                               'size' => 1,
-                               'minitems' => 1,
-                               'maxitems' => 1
-                       )
-               ),
-
-               'products' => array(
-                       'exclude' => 0,
-                       'label' => STOREFINDERLLFILE . 'tx_storefinder_domain_model_location.products',
-                       'config' => array(
-                               'type' => 'input',
-                               'size' => '50',
-                               'eval' => 'trim',
-                               'max' => '255',
-                       )
-               ),
-
-               'phone' => array(
-                       'exclude' => 0,
-                       'label' => STOREFINDERLLFILE . 'tx_storefinder_domain_model_location.phone',
-                       'config' => array(
-                               'type' => 'input',
-                               'size' => '30',
-                               'eval' => 'trim',
-                       )
-               ),
-
-               'mobile' => array(
-                       'exclude' => 0,
-                       'label' => STOREFINDERLLFILE . 'tx_storefinder_domain_model_location.mobile',
-                       'config' => array(
-                               'type' => 'input',
-                               'size' => '30',
-                               'eval' => 'trim',
-                       )
-               ),
-
-               'fax' => array(
-                       'exclude' => 0,
-                       'label' => STOREFINDERLLFILE . 'tx_storefinder_domain_model_location.fax',
-                       'config' => array(
-                               'type' => 'input',
-                               'size' => '30',
-                               'eval' => 'trim',
-                       )
-               ),
-
-               'email' => array(
-                       'exclude' => 0,
-                       'label' => STOREFINDERLLFILE . 'tx_storefinder_domain_model_location.email',
-                       'config' => array(
-                               'type' => 'input',
-                               'size' => '30',
-                               'eval' => 'trim',
-                       )
-               ),
-
-               'hours' => array(
-                       'exclude' => 0,
-                       'label' => STOREFINDERLLFILE . 'tx_storefinder_domain_model_location.hours',
-                       'config' => array(
-                               'type' => 'text',
-                               'cols' => '30',
-                               'rows' => '5',
-                       )
-               ),
-
-               'url' => array(
-                       'exclude' => 0,
-                       'label' => STOREFINDERLLFILE . 'tx_storefinder_domain_model_location.url',
-                       'config' => array(
-                               'type' => 'input',
-                               'size' => '30',
-                               'max' => '255',
-                               'eval' => 'trim',
-                               'wizards' => Array(
-                                       '_PADDING' => 2,
-                                       'link' => Array(
-                                               'type' => 'popup',
-                                               'title' => 'Link',
-                                               'icon' => 'link_popup.gif',
-                                               'script' => 'browse_links.php?mode=wizard',
-                                               'JSopenParams' => 'height=300,width=500,status=0,menubar=0,scrollbars=1'
-                                       )
-                               )
-                       )
-               ),
-
-               'notes' => array(
-                       'exclude' => 0,
-                       'label' => STOREFINDERLLFILE . 'tx_storefinder_domain_model_location.notes',
-                       'config' => array(
-                               'type' => 'text',
-                               'cols' => '30',
-                               'rows' => '5',
-                       )
-               ),
-
-               'media' => array(
-                       'exclude' => 0,
-                       'label' => STOREFINDERLLFILE . 'tx_storefinder_domain_model_location.media',
-                       'config' => array(
-                               'type' => 'group',
-                               'internal_type' => 'file',
-                               'allowed' => 'txt,html,htm,class,swf,swa,dcr,wav,avi,au,mov,asf,mpg,wmv,mp3,mp4,m4v',
-                               'max_size' => $GLOBALS['TYPO3_CONF_VARS']['BE']['maxFileSize'],
-                               'uploadfolder' => 'uploads/media',
-                               'size' => '2',
-                               'maxitems' => '1',
-                               'minitems' => '0',
-                       ),
-               ),
-
-               'image' => array(
-                       'exclude' => 0,
-                       'label' => STOREFINDERLLFILE . 'tx_storefinder_domain_model_location.image',
-                       'config' => array(
-                               'type' => 'group',
-                               'internal_type' => 'file',
-                               'allowed' => $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'],
-                               'max_size' => $GLOBALS['TYPO3_CONF_VARS']['BE']['maxFileSize'],
-                               'uploadfolder' => 'uploads/pics',
-                               'show_thumbs' => '1',
-                               'size' => '3',
-                               'maxitems' => '200',
-                               'minitems' => '0',
-                               'autoSizeMax' => 40,
-                       ),
-               ),
-
-               'icon' => array(
-                       'exclude' => 0,
-                       'label' => STOREFINDERLLFILE . 'tx_storefinder_domain_model_location.icon',
-                       'config' => array(
-                               'type' => 'select',
-                               'items' => array(),
-                               'size' => 1,
-                               'maxitems' => 1,
-                       )
-               ),
-
-               'categories' => array(
-                       'label' => 'LLL:EXT:lang/locallang_tca.xlf:category_perms',
-                       'config' => array(
-                               'type' => 'select',
-                               'foreign_table' => 'sys_category',
-                               'foreign_table_where' => ' AND (sys_category.sys_language_uid = 0 OR sys_category.l10n_parent = 0) ORDER BY sys_category.sorting',
-                               'MM' => 'sys_category_record_mm',
-                               'MM_opposite_field' => 'items',
-                               'MM_match_fields' => array(
-                                       'tablenames' => 'tx_storefinder_domain_model_location',
-                                       'fieldname' => 'categories',
-                               ),
-                               'renderMode' => 'tree',
-                               'treeConfig' => array(
-                                       'parentField' => 'parent',
-                                       'appearance' => array(
-                                               'expandAll' => FALSE,
-                                               'showHeader' => FALSE,
-                                               'maxLevels' => 99,
-                                       ),
-                               ),
-                               'size' => 10,
-                               'autoSizeMax' => 20,
-                               'minitems' => 0,
-                               'maxitems' => 9999,
-                               'wizards' => array(
-                                       'add' => array(
-                                               'type' => 'script',
-                                               'title' => STOREFINDERLLFILE . 'sys_category.add',
-                                               'icon' => 'add.gif',
-                                               'params' => array(
-                                                       'table' => 'sys_category',
-                                                       'pid' => '###CURRENT_PID###',
-                                                       'setValue' => 'prepend'
-                                               ),
-                                               'script' => 'wizard_add.php',
-                                       )
-                               ),
-                       )
-               ),
-
-               'latitude' => array(
-                       'exclude' => 0,
-                       'label' => STOREFINDERLLFILE . 'tx_storefinder_domain_model_location.latitude',
-                       'config' => array(
-                               'type' => 'input',
-                               'readOnly' => 1,
-                               'size' => 10,
-                       )
-               ),
-
-               'longitude' => array(
-                       'exclude' => 0,
-                       'label' => STOREFINDERLLFILE . 'tx_storefinder_domain_model_location.longitude',
-                       'config' => array(
-                               'type' => 'input',
-                               'readOnly' => 1,
-                               'size' => 10,
-                       )
-               ),
-
-               'use_as_center' => array(
-                       'exclude' => 1,
-                       'label' => STOREFINDERLLFILE . 'tx_storefinder_domain_model_location.use_as_center',
-                       'config' => array(
-                               'type' => 'check',
-                       )
-               ),
-
-               'content' => array(
-                       'exclude' => 1,
-                       'label' => STOREFINDERLLFILE . 'tx_storefinder_domain_model_location.content',
-                       'config' => array(
-                               'type' => 'inline',
-                               'allowed' => 'tt_content',
-                               'foreign_table' => 'tt_content',
-                               'minitems' => 0,
-                               'maxitems' => 10,
-                               'appearance' => array(
-                                       'collapseAll' => 1,
-                                       'expandSingle' => 1,
-                                       'levelLinksPosition' => 'bottom',
-                                       'useSortable' => 1,
-                                       'showPossibleLocalizationRecords' => 1,
-                                       'showRemovedLocalizationRecords' => 1,
-                                       'showAllLocalizationLink' => 1,
-                                       'showSynchronizationLink' => 1,
-                                       'enabledControls' => array(
-                                               'info' => FALSE,
-                                       )
-                               )
-                       )
-               ),
-       ),
-
-       'types' => array(
-               '0' => array('showitem' => '
-                       --div--;' . STOREFINDERLLFILE . 'div-address,
-                               name, storeid, address, additionaladdress, zipcode, city, state, country,
-                       --div--;' . STOREFINDERLLFILE . 'div-contact,
-                               person, phone, mobile, fax, email, hours,
-                       --div--;' . STOREFINDERLLFILE . 'div-informations,
-                               products, notes, url, image, media, content,
-                       --div--;' . STOREFINDERLLFILE . 'div-relations,
-                               --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.access;access,
-                               related, categories, attributes, icon, latitude, longitude, use_as_center')
-       ),
-
-       'palettes' => array(
-               'access' => array(
-                       'showitem' => '
-                               hidden;' . STOREFINDERLLFILE . 'tx_storefinder_domain_model_location.hidden, --linebreak--,
-                               starttime;LLL:EXT:cms/locallang_ttc.xml:starttime_formlabel,
-                               endtime;LLL:EXT:cms/locallang_ttc.xml:endtime_formlabel, --linebreak--,
-                               fe_group;LLL:EXT:cms/locallang_ttc.xml:fe_group_formlabel',
-                       'canNotCollapse' => 1,
-               ),
-       )
-);
-
-?>
\ No newline at end of file
index c03025b..21244b3 100644 (file)
@@ -1,4 +1,11 @@
 plugin.tx_storefinder.settings {
+       geocodeUrl = http://maps.googleapis.com/maps/api/geocode/json?sensor=false
+
+       limit = 20
+
+       # [miles, kilometer]
+       distanceUnit = miles
+
        mapConfiguration {
                # traffic, weather, bicycling,  panoramio, kml
                apiV3Layers =
@@ -12,11 +19,12 @@ plugin.tx_storefinder.settings {
        }
 }
 
-plugin.tx_storefinder.persistence {
+config.tx_extbase.persistence {
        classes {
-               Evoweb\StoreFinder\Domain\Model\StaticCountry.mapping.tableName = static_countries
-               Evoweb\StoreFinder\Domain\Model\StaticCountryZone.mapping.tableName = static_country_zones
-               Evoweb\StoreFinder\Domain\Model\StaticLanguage.mapping.tableName = static_languages
+               Evoweb\StoreFinder\Domain\Model\Country.mapping.tableName = static_countries
+               Evoweb\StoreFinder\Domain\Model\CountryZone.mapping.tableName = static_country_zones
+
+               Evoweb\StoreFinder\Domain\Model\Category.mapping.tableName = sys_category
        }
 }
 
diff --git a/Documentation/license.txt b/Documentation/license.txt
new file mode 100644 (file)
index 0000000..076fdc8
--- /dev/null
@@ -0,0 +1,6 @@
+Wizard Icon
+Resources/Public/Icons/google-maps-icon.png
+Url: http://www.iconarchive.com/show/google-play-icons-by-marcus-roberto/Google-Maps-icon.html
+Artist: Marcus Roberto
+Artist-Url: http://marcus-roberto.deviantart.com
+License: Free for personal desktop use only.
\ No newline at end of file
index f2dc7be..1e56bc9 100644 (file)
@@ -8,20 +8,11 @@
        </meta>
        <data type="array">
                <languageKey index="default" type="array">
-                       <label index="pi1_title">Store Finder</label>
-                       <label index="pi1_plus_wiz_description">Adds a store finder search form to the page.</label>
-                       <label index="tt_content.list_type_map">Store Finder</label>
-
                        <label index="apiConsoleKey">Api Console Key (Google Maps API for Business only)</label>
                        <label index="geocodeUrl">Url used for geocode</label>
 
-                       <label index="pi_flexform.sheetGeneralOptions">General options</label>
-                       <label index="pi_flexform.googleApiVersion.label">Google API version (default 3.x, 3.s, 3...)</label>
-                       <label index="pi_flexform.useCurl.label">Use curl</label>
                        <label index="pi_flexform.showOverviewMap.label">Show overview map in result table</label>
                        <label index="pi_flexform.searchByName.label">Search by name (only store_finder tables)</label>
-                       <label index="pi_flexform.resultPageId.label">Result page</label>
-                       <label index="pi_flexform.routePageId.label">Route page id</label>
                        <label index="pi_flexform.feUserListingPageId.label">feUserListing page id (only FE user)</label>
                        <label index="pi_flexform.helpPageId.label">Help page id</label>
                        <label index="pi_flexform.useNotesInternal.label">Use notes internal</label>
@@ -36,7 +27,6 @@
                        <label index="pi_flexform.tt_addressnameField.label">tt_address name Field</label>
                        <label index="pi_flexform.numberOfMails.label">Number of mails generated</label>
                        <label index="pi_flexform.showOnlyMailResultTable.label">Show only mail result table</label>
-                       <label index="pi_flexform.showStoreImage.label">Show store image in list</label>
                        <label index="pi_flexform.countryCodes.label">Allowed country codes in search form</label>
                        <label index="pi_flexform.radiusPresets.label">Radius presets in km/miles</label>
                        <label index="pi_flexform.resultLimit.label">Result limit</label>
@@ -45,7 +35,6 @@
                        <label index="pi_flexform.sheetDisplayOptions">Display options</label>
                        <label index="pi_flexform.useFeUserPageTitle.label">Use page title from FE user (single view)</label>
                        <label index="pi_flexform.storeTitle.label">store title</label>
-                       <label index="pi_flexform.displayMode.label">display mode</label>
                        <label index="pi_flexform.linkTarget.label">target of links</label>
                        <label index="pi_flexform.routeViewTarget.label">target of routeview</label>
                        <label index="pi_flexform._top.label">_top</label>
@@ -56,8 +45,6 @@
                        <label index="pi_flexform.mapAllNoFormView.label">display all stores in a map without form</label>
                        <label index="pi_flexform.routeView.label">displays driving routes</label>
                        <label index="pi_flexform.single.label">single view</label>
-                       <label index="pi_flexform.zipcodeAreaView.label">show zipcode areas</label>
-                       <label index="pi_flexform.zipcodeAreaNoFormView.label">show zipcode areas without form</label>
                        <label index="pi_flexform.listView.label">show list of stores (only for store finder tables)</label>
                        <label index="pi_flexform.countryCitySelector.label">country city selector</label>
                        <label index="pi_flexform.shopFinder.label">shop template</label>
                        <label index="pi_flexform.ajaxSearchWithMap.label">ajax search with map</label>
                        <label index="pi_flexform.showPoiTable.label">show POI table (not in route view and not in normal map view)</label>
                        <label index="pi_flexform.enableMoreButton.label">enable overlays button</label>
-                       <label index="pi_flexform.apiV3Layers.label">additional overlays in api v3</label>
-                       <label index="pi_flexform.trafficOverlay.label">traffic</label>
-                       <label index="pi_flexform.weatherOverlay.label">weather</label>
-                       <label index="pi_flexform.bicyclingOverlay.label">bicycling</label>
-                       <label index="pi_flexform.panoramioOverlay.label">panoramio</label>
-                       <label index="pi_flexform.kmlOverlay.label">kml</label>
                        <label index="pi_flexform.additionalLayers.label">additional overlays api v2</label>
                        <label index="pi_flexform.enableStreetViewOverlay.label">enable street view overlay</label>
                        <label index="pi_flexform.enableStreetView.label">enable street view</label>
                        <label index="pi_flexform.restaurantFinder.label">restaurant template</label>
                        <label index="pi_flexform.sheetShapeAreaOptions">shape area options</label>
                        <label index="pi_flexform.shapeFile.label">shapefile</label>
-                       <label index="pi_flexform.fillZipcodeArea.label">fill zipcode area</label>
-                       <label index="pi_flexform.zoomZipcodeArea.label">zoom zipcode areas [0-17]</label>
                        <label index="pi_flexform.sheetCookieOptions">cookie options</label>
                        <label index="pi_flexform.useCookie.label">use cookie</label>
                        <label index="pi_flexform.cookieLifeTime.label">cookie life time [sec]</label>
 
-                       <label index="pi_flexform.switchableControllerActions.searchAndMapList">Search and Map with List</label>
-                       <label index="pi_flexform.switchableControllerActions.search">Search</label>
-                       <label index="pi_flexform.switchableControllerActions.map">Map</label>
-                       <label index="pi_flexform.switchableControllerActions.list">List</label>
-                       <label index="pi_flexform.switchableControllerActions.mapList">Map with List</label>
-                       <label index="pi_flexform.switchableControllerActions.searchMapList">Search with Map and with List</label>
-               </languageKey>
-               <languageKey index="de" type="array">
-                       <label index="pi1_title">Storefinder</label>
-                       <label index="pi1_plus_wiz_description">Fügt ein Suchformular für den Filialfinder der Seite hinzu.</label>
-                       <label index="tt_content.list_type_pi1">Store Finder</label>
+                       <label index="pi1_title">Store Finder</label>
+                       <label index="tt_content.list_type_map">Store Finder</label>
+                       <label index="pi1_plus_wiz_description">Adds a store finder search form to the page.</label>
 
-                       <label index="pi_flexform.sheetGeneralOptions">Allgemeine Optionen</label>
-                       <label index="pi_flexform.googleApiVersion.label">Google API Version (3.x, 3.s, 3...)</label>
-                       <label index="pi_flexform.useCurl.label">Benutze PHP curl</label>
-                       <label index="pi_flexform.showOverviewMap.label">Zeige Übersichtskarte nach Ergebnistabelle</label>
-                       <label index="pi_flexform.searchByName.label">Suche nach Namen (nur store finder Tabellen)</label>
-                       <label index="pi_flexform.resultPageId.label">Ergebnisseite</label>
-                       <label index="pi_flexform.routePageId.label">Fahrtrouteseite</label>
-                       <label index="pi_flexform.feUserListingPageId.label">Fe UserListing Seiten Uid (nur FE user)</label>
-                       <label index="pi_flexform.helpPageId.label">Hilfeseite Suchformular</label>
-                       <label index="pi_flexform.useNotesInternal.label">Benutze Bemerkungen intern</label>
-                       <label index="pi_flexform.useStoreFinderTable.label">Benutze Store Finder Daten von</label>
-                       <label index="pi_flexform.useStoreFinderData.label">Store Finder Tabelle</label>
-                       <label index="pi_flexform.useFeUserData.label">Fe User Tabelle</label>
-                       <label index="pi_flexform.useExternalTable.label">Externe Lokationstabelle</label>
-                       <label index="pi_flexform.useTt_newsTable.label">tt_news Tabelle</label>
-                       <label index="pi_flexform.useTt_addressTable.label">tt_address Tabelle</label>
-                       <label index="pi_flexform.externalLocationTable.label">Externe Lokationstabelle</label>
-                       <label index="pi_flexform.feUserGroup.label">FE User Gruppe</label>
-                       <label index="pi_flexform.tt_addressnameField.label">tt_address name Feld</label>
-                       <label index="pi_flexform.numberOfMails.label">Anzahl der generierten Mails</label>
-                       <label index="pi_flexform.showOnlyMailResultTable.label">Zeige nur Mail Tabelle</label>
-                       <label index="pi_flexform.showStoreImage.label">Zeige Filialimage in Liste</label>
-                       <label index="pi_flexform.countryCodes.label">Zulässige Ländercodes im Suchformular</label>
-                       <label index="pi_flexform.radiusPresets.label">Radius presets in km/Meilen</label>
-                       <label index="pi_flexform.resultLimit.label">Maximale Anzahl Ergebnisse</label>
-                       <label index="pi_flexform.enableLogs.label">Protokolleinträge aktivieren</label>
-                       <label index="pi_flexform.debug.label">Debug (in Verbindung mit cc_debug)</label>
-                       <label index="pi_flexform.sheetDisplayOptions">Anzeige Optionen</label>
-                       <label index="pi_flexform.useFeUserPageTitle.label">Seitentitel FE User (Einzelansicht)</label>
-                       <label index="pi_flexform.storeTitle.label">Filialtitel</label>
-                       <label index="pi_flexform.displayMode.label">Darstellung</label>
-                       <label index="pi_flexform.linkTarget.label">Target der Links</label>
-                       <label index="pi_flexform.routeViewTarget.label">Target des Anfahrtsweges</label>
-                       <label index="pi_flexform._top.label">_top</label>
-                       <label index="pi_flexform._blank.label">_blank</label>
-                       <label index="pi_flexform.mapView.label">Normale Kartendarstellung</label>
-                       <label index="pi_flexform.allMapView.label">Alle Filialen in der Karte anzeigen</label>
-                       <label index="pi_flexform.mapAllNoFormView.label">Alle Filialen ohne Startpunkt</label>
-                       <label index="pi_flexform.routeView.label">Fahrtrouten anzeigen</label>
-                       <label index="pi_flexform.single.label">Einzelansicht</label>
-                       <label index="pi_flexform.zipcodeAreaView.label">Postleitzahlgebiete</label>
-                       <label index="pi_flexform.zipcodeAreaNoFormView.label">Postleitzahlengebiete ohne Startpunkt</label>
-                       <label index="pi_flexform.listView.label">Listenansicht nur Store Finder Tabellen</label>
-                       <label index="pi_flexform.countryCitySelector.label">Land Stadt Selektor</label>
-                       <label index="pi_flexform.shopFinder.label">Shop Template</label>
-                       <label index="pi_flexform.searchFormView.label">Suchformular</label>
-                       <label index="pi_flexform.catMenu.label">Kategoriemenü</label>
-                       <label index="pi_flexform.ajaxSearchWithMap.label">ajax Suche mit Karte</label>
-                       <label index="pi_flexform.showPoiTable.label">Aktiviere POI Tabelle (nicht in Routeview und nicht in normale Karte)</label>
-                       <label index="pi_flexform.enableMoreButton.label">Aktiviere Weitere Overlays</label>
-                       <label index="pi_flexform.additionalLayers.label">Zusätzliche Overlays</label>
-                       <label index="pi_flexform.enableStreetViewOverlay.label">Aktiviere Street View Overlay</label>
-                       <label index="pi_flexform.enableStreetView.label">Aktiviere Panorama</label>
-                       <label index="pi_flexform.uidOfSingle.label">Uid der Einzelansicht (default 1)</label>
-                       <label index="pi_flexform.showTabbedInfoWindow.label">Zeige Infowindow mit Tabs</label>
-                       <label index="pi_flexform.showVideoPlayer.label">Aktiviere Video im infoWindow</label>
-                       <label index="pi_flexform.autoMailView.label">automatische Mails</label>
-                       <label index="pi_flexform.distanceUnit.label">Entfernungsangaben in</label>
-                       <label index="pi_flexform.unitKm.label">km</label>
-                       <label index="pi_flexform.unitMiles.label">Meilen</label>
-                       <label index="pi_flexform.apiV3Layers.label">Zusätzliche Overlays in api v3</label>
-                       <label index="pi_flexform.trafficOverlay.label">Verkehr</label>
-                       <label index="pi_flexform.weatherOverlay.label">Wetter</label>
-                       <label index="pi_flexform.bicyclingOverlay.label">Fahrradwege</label>
-                       <label index="pi_flexform.panoramioOverlay.label">Panoramio</label>
-                       <label index="pi_flexform.additionalMapTypes.label">zusätzliche Kartentypen api v2</label>
-                       <label index="pi_flexform.sheetTemplateOptions">Template Optionen</label>
-                       <label index="pi_flexform.templateFile.label">Template Datei</label>
-                       <label index="pi_flexform.cssFile.label">CSS Datei</label>
-                       <label index="pi_flexform.finderTemplate.label">Finder Template</label>
-                       <label index="pi_flexform.restaurantFinder.label">Restaurant Template</label>
-                       <label index="pi_flexform.sheetShapeAreaOptions">Shape Optionen</label>
-                       <label index="pi_flexform.shapeFile.label">Shape Datei</label>
-                       <label index="pi_flexform.fillZipcodeArea.label">Shape Gebiet füllen</label>
-                       <label index="pi_flexform.zoomZipcodeArea.label">Zoom Shape Gebiete [0-17]</label>
-                       <label index="pi_flexform.sheetCookieOptions">Cookie options</label>
-                       <label index="pi_flexform.useCookie.label">Cookie aktivieren</label>
-                       <label index="pi_flexform.cookieLifeTime.label">Cookie life time [sec]</label>
+                       <label index="pi_flexform.sheetDisplayOptions">Display options</label>
+                       <label index="pi_flexform.showBeforeSearch">Show before search</label>
+                       <label index="pi_flexform.showAfterSearch">Show after search</label>
+                       <label index="pi_flexform.showItems.search">Search</label>
+                       <label index="pi_flexform.showItems.map">Map</label>
+                       <label index="pi_flexform.showItems.list">List</label>
+                       <label index="pi_flexform.showStoreImage">Show store image in list</label>
+                       <label index="pi_flexform.apiV3Layers">additional overlays in api v3</label>
+                       <label index="pi_flexform.apiV3Layers.trafficOverlay">traffic</label>
+                       <label index="pi_flexform.apiV3Layers.weatherOverlay">weather</label>
+                       <label index="pi_flexform.apiV3Layers.bicyclingOverlay">bicycling</label>
+                       <label index="pi_flexform.apiV3Layers.panoramioOverlay">panoramio</label>
+                       <label index="pi_flexform.apiV3Layers.kmlOverlay">kml</label>
+                       <label index="pi_flexform.allowedCountries">Countries allowed in search country selectbox</label>
+                       <label index="pi_flexform.templateRootPath">Template path</label>
+                       <label index="pi_flexform.partialRootPath">Partial path</label>
+
+                       <label index="pi_flexform.sheetReferenceOptions">Reference options</label>
+                       <label index="pi_flexform.resultPageId">Result page</label>
+                       <label index="pi_flexform.routePageId">Routing page id</label>
+                       <label index="pi_flexform.singleLocationId">Single location to render</label>
+                       <label index="pi_flexform.categories">Categories</label>
+                       <label index="pi_flexform.categoryPriority">Category used for</label>
+                       <label index="pi_flexform.categoryPriority.useAsFilterInFrontend">Filter utilized by the user in frontend</label>
+                       <label index="pi_flexform.categoryPriority.limitResultsToCategories">Filter used for the query without user utilization</label>
+                       <label index="pi_flexform.categoryPriority.useParentIfNoFilterSelected">Filter utilized by the user in frontend or as filter if the user selected none</label>
                </languageKey>
        </data>
 </T3locallang>
\ No newline at end of file
index 82058c5..8a0d170 100644 (file)
@@ -9,7 +9,7 @@
                        <label index="tx_storefinder_domain_model_location">Store Location</label>
                        <label index="tx_storefinder_domain_model_location.hidden">Location</label>
                        <label index="tx_storefinder_domain_model_location.name">Store Name</label>
-                       <label index="tx_storefinder_domain_model_location.related">Related to (Uid)</label>
+                       <label index="tx_storefinder_domain_model_location.related">Related to location</label>
                        <label index="tx_storefinder_domain_model_location.storeid">Store Id</label>
                        <label index="tx_storefinder_domain_model_location.attributes">Attributes</label>
                        <label index="tx_storefinder_domain_model_location.address">Address</label>
                        <label index="tx_storefinder_domain_model_location.url">URL</label>
                        <label index="tx_storefinder_domain_model_location.notes">Notes</label>
                        <label index="tx_storefinder_domain_model_location.media">Media</label>
-                       <label index="tx_storefinder_domain_model_location.image">Image</label>
+                       <label index="tx_storefinder_domain_model_location.image">Images</label>
                        <label index="tx_storefinder_domain_model_location.icon">Icon</label>
                        <label index="tx_storefinder_domain_model_location.content">Content Elements</label>
                        <label index="tx_storefinder_domain_model_location.categories">Categories</label>
                        <label index="tx_storefinder_domain_model_location.latitude">Latitude</label>
                        <label index="tx_storefinder_domain_model_location.longitude">Longitude</label>
-                       <label index="tx_storefinder_domain_model_location.use_as_center">Use as center</label>
+                       <label index="tx_storefinder_domain_model_location.center">Use as center</label>
+                       <label index="tx_storefinder_domain_model_location.distance">Calculated value by search query</label>
 
                        <label index="sys_category.add">Add category</label>
 
                        <label index="div-informations">Informations</label>
                        <label index="div-relations">Relations</label>
 
+                       <label index="palette-coordinates">Coordinates</label>
+
                        <label index="tx_storefinder_domain_model_attribute">Store Attributes</label>
                        <label index="tx_storefinder_domain_model_attribute.name">Name</label>
                        <label index="tx_storefinder_domain_model_attribute.icon">Icon</label>
-
-                       <label index="tx_storefinder_domain_model_zipcodearea">Store Zipcode Areas</label>
-                       <label index="tx_storefinder_domain_model_zipcodearea.zipcode">Zipcode</label>
-                       <label index="tx_storefinder_domain_model_zipcodearea.area">Area-No.</label>
-                       <label index="tx_storefinder_domain_model_zipcodearea.latitude">Latitude</label>
-                       <label index="tx_storefinder_domain_model_zipcodearea.longitude">Longitude</label>
-
-                       <label index="fe_users.tx_storefinder_latitude">tx_storefinder[latitude]</label>
-                       <label index="fe_users.tx_storefinder_longitude">tx_storefinder[longitude]</label>
-
-                       <label index="tt_address.tx_storefinder_latitude">tx_storefinder[latitude]</label>
-                       <label index="tt_address.tx_storefinder_longitude">tx_storefinder[longitude]</label>
                </languageKey>
                <languageKey index="de" type="array">
                        <label index="tx_storefinder_domain_model_location">Store</label>