diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e35a6d9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2010 Thibault Duplessis + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/README.markdown b/README.markdown new file mode 100644 index 0000000..2913e5f --- /dev/null +++ b/README.markdown @@ -0,0 +1,8 @@ +dmGoogleMapPlugin allows to display configurable google maps. +It packages a Diem front widget, and adds a _map() helper. +The plugin is fully extensible. Only works with [Diem 5.0](http://diem-project.org/) installed. + +Documentation +------------- + +See the online documentation : [Diem Google Map plugin documentation](http://diem-project.org/plugins/dmgooglemapplugin) diff --git a/config/dm/assets.yml b/config/dm/assets.yml new file mode 100644 index 0000000..69bc448 --- /dev/null +++ b/config/dm/assets.yml @@ -0,0 +1,10 @@ +js: + + dmGoogleMapPlugin: + + api: http://maps.google.com/maps/api/js?sensor=false + + widgetShowForm: widget/showForm + + launcher: launcher + dmGoogleMap: dmGoogleMap \ No newline at end of file diff --git a/config/dm/services.yml b/config/dm/services.yml new file mode 100644 index 0000000..2c7afff --- /dev/null +++ b/config/dm/services.yml @@ -0,0 +1,18 @@ +parameters: + + google_map_tag.class: dmGoogleMapTag + google_map_tag.options: [] + + google_map_helper.class: dmGoogleMapHelper + +services: + + google_map_tag: + class: %google_map_tag.class% + shared: false + arguments: [ %google_map_tag.options% ] + + google_map_helper: + class: %google_map_helper.class% + shared: true + arguments: [ @context ] \ No newline at end of file diff --git a/config/dm/widget_types.yml b/config/dm/widget_types.yml new file mode 100644 index 0000000..3e09fc3 --- /dev/null +++ b/config/dm/widget_types.yml @@ -0,0 +1,5 @@ +dmWidgetGoogleMap: + + show: + cache: false + public_name: Google Map \ No newline at end of file diff --git a/lib/dmWidget/dmWidgetGoogleMapShowForm.php b/lib/dmWidget/dmWidgetGoogleMapShowForm.php new file mode 100644 index 0000000..f83703c --- /dev/null +++ b/lib/dmWidget/dmWidgetGoogleMapShowForm.php @@ -0,0 +1,115 @@ +widgetSchema['address'] = new sfWidgetFormInputText(); + $this->validatorSchema['address'] = new sfValidatorString(); + $this->widgetSchema['address']->setLabel('Search a place'); + + $this->widgetSchema['mapTypeId'] = new sfWidgetFormSelect(array( + 'choices' => dmArray::valueToKey($this->getMapTypeIds()) + )); + $this->validatorSchema['mapTypeId'] = new sfValidatorChoice(array( + 'choices' => $this->getMapTypeIds() + )); + $this->widgetSchema['mapTypeId']->setLabel('Map type'); + + $this->widgetSchema['zoom'] = new sfWidgetFormSelect(array( + 'choices' => dmArray::valueToKey($this->getZooms()) + )); + $this->validatorSchema['zoom'] = new sfValidatorChoice(array( + 'choices' => $this->getZooms() + )); + + $this->widgetSchema['navigationControl'] = new sfWidgetFormInputCheckbox(); + $this->validatorSchema['navigationControl'] = new sfValidatorBoolean(); + $this->widgetSchema['navigationControl']->setLabel('Navigation'); + + $this->widgetSchema['mapTypeControl'] = new sfWidgetFormInputCheckbox(); + $this->validatorSchema['mapTypeControl'] = new sfValidatorBoolean(); + $this->widgetSchema['mapTypeControl']->setLabel('Map type'); + + $this->widgetSchema['scaleControl'] = new sfWidgetFormInputCheckbox(); + $this->validatorSchema['scaleControl'] = new sfValidatorBoolean(); + $this->widgetSchema['scaleControl']->setLabel('Scale'); + + $this->widgetSchema['width'] = new sfWidgetFormInputText(array(), array('size' => 5)); + $this->validatorSchema['width'] = new dmValidatorCssSize(array( + 'required' => false + )); + + $this->widgetSchema['height'] = new sfWidgetFormInputText(array(), array('size' => 5)); + $this->validatorSchema['height'] = new dmValidatorCssSize(array( + 'required' => false + )); + + $this->widgetSchema['splash'] = new sfWidgetFormInputText(); + $this->validatorSchema['splash'] = new sfValidatorString(array( + 'required' => false + )); + $this->widgetSchema->setHelp('splash', 'Display a message while the map is loading'); + + if(!$this->getDefault('width')) + { + $this->setDefault('width', '100%'); + } + if(!$this->getDefault('height')) + { + $this->setDefault('height', '300px'); + } + if(!$this->getDefault('mapTypeId')) + { + $this->setDefault('mapTypeId', 'hybrid'); + } + if(!$this->getDefault('zoom')) + { + $this->setDefault('zoom', '14'); + } + + parent::configure(); + } + + protected function getMapTypeIds() + { + return array('roadmap', 'satellite', 'hybrid', 'terrain'); + } + + protected function getZooms() + { + return range(2, 20); + } + + public function getStylesheets() + { + return array( + 'lib.ui-tabs' + ); + } + + public function getJavascripts() + { + return array( + 'lib.ui-tabs', + 'core.tabForm', + 'dmGoogleMapPlugin.widgetShowForm' + ); + } + + protected function renderContent($attributes) + { + return $this->getHelper()->renderPartial('dmWidgetGoogleMap', 'showForm', array( + 'form' => $this, + 'baseTabId' => 'dm_widget_google_map_'.$this->dmWidget->get('id') + )); + } + + public function getWidgetValues() + { + $values = parent::getWidgetValues(); + + return $values; + } +} \ No newline at end of file diff --git a/lib/dmWidget/dmWidgetGoogleMapShowView.php b/lib/dmWidget/dmWidgetGoogleMapShowView.php new file mode 100644 index 0000000..1b96f0e --- /dev/null +++ b/lib/dmWidget/dmWidgetGoogleMapShowView.php @@ -0,0 +1,53 @@ +addRequiredVar(array( + 'address', + 'mapTypeId', + 'zoom', + 'navigationControl', + 'mapTypeControl', + 'scaleControl', + 'width', + 'height')); + } + + protected function doRender() + { + $vars = $this->getViewVars(); + + $map = $this->getService('google_map_helper')->map() + ->address($vars['address']) + ->mapTypeId($vars['mapTypeId']) + ->zoom($vars['zoom']) + ->style(sprintf( + 'width: %s; height: %s;', + dmArray::get($vars, 'width', '100%'), + dmArray::get($vars, 'height', '300px') + )) + ->navigationControl($vars['navigationControl']) + ->mapTypeControl($vars['mapTypeControl']) + ->scaleControl($vars['scaleControl']) + ->splash($vars['splash']); + + $this + ->addJavascript($map->getJavascripts()) + ->addStylesheet($map->getStylesheets()); + + return $map; + } + + protected function doRenderForIndex() + { + $vars = $this->getViewVars(); + + return $vars['address']; + } + +} \ No newline at end of file diff --git a/lib/helper/DmGoogleMapHelper.php b/lib/helper/DmGoogleMapHelper.php new file mode 100644 index 0000000..8680748 --- /dev/null +++ b/lib/helper/DmGoogleMapHelper.php @@ -0,0 +1,17 @@ +get('google_map_helper')->map(); +} + +/* + * Alternative to £map + */ +function £map() +{ + return _map(); +} \ No newline at end of file diff --git a/lib/view/dmGoogleMapHelper.php b/lib/view/dmGoogleMapHelper.php new file mode 100644 index 0000000..c138a3d --- /dev/null +++ b/lib/view/dmGoogleMapHelper.php @@ -0,0 +1,55 @@ +context = $context; + + $this->initialize($options); + } + + public function initialize(array $options) + { + $this->configure($options); + } + + /* + * Get a dmGoogleMapTag instance + */ + public function map() + { + $map = $this->context->get('google_map_tag'); + + $response = $this->context->getResponse(); + + foreach($map->getStylesheets() as $stylesheet) + { + $response->addStylesheet($stylesheet); + } + + foreach($map->getJavascripts() as $javascript) + { + $response->addJavascript($javascript); + } + + /* + * Async loading won't work + * as the api itself uses async loading + */ + if(!$this->context->getRequest()->isXmlHttpRequest()) + { + $response->addJavascript('dmGoogleMapPlugin.api'); + } + + return $map; + } + + public function £map() + { + return $this->map(); + } +} \ No newline at end of file diff --git a/lib/view/html/dmGoogleMapTag.php b/lib/view/html/dmGoogleMapTag.php new file mode 100644 index 0000000..be1a82c --- /dev/null +++ b/lib/view/html/dmGoogleMapTag.php @@ -0,0 +1,127 @@ +initialize($options); + } + + public function initialize(array $options = array()) + { + parent::initialize($options); + + $this + ->addAttributeToRemove(array('splash')) + ->addClass('dm_google_map') + ->setOption('mapTypeId', 'hybrid') + ->setOption('zoom', 14) + ->setOption('splash', ''); + } + + public function getDefaultOptions() + { + return array_merge(parent::getDefaultOptions(), array( + 'address' => null, + 'coords' => null + )); + } + + /* + * Change the splash + */ + public function splash($splash) + { + return $this->setOption('splash', (string) $splash); + } + + public function address($location) + { + return $this->setOption('address', (string) $location); + } + + public function coords($latitude, $longitude) + { + return $this->setOption('coords', array($latitude, $longitude)); + } + + public function mapTypeId($mapType) + { + return $this->setOption('mapTypeId', (string) $mapType); + } + + public function zoom($zoom) + { + return $this->setOption('zoom', (int) $zoom); + } + + public function navigationControl($bool) + { + return $this->setOption('navigationControl', (bool) $bool); + } + + public function mapTypeControl($bool) + { + return $this->setOption('mapTypeControl', (bool) $bool); + } + + public function scaleControl($bool) + { + return $this->setOption('scaleControl', (bool) $bool); + } + + public function render() + { + $preparedAttributes = $this->prepareAttributesForHtml($this->options); + + $splash = $preparedAttributes['splash']; + unset($preparedAttributes['splash']); + + $tag = 'convertAttributesToHtml($preparedAttributes).'>'.$splash.''; + + return $tag; + } + + protected function prepareAttributesForHtml(array $attributes) + { + return $this->jsonifyAttributes($attributes); + } + + protected function jsonifyAttributes(array $attributes) + { + $jsonAttributes = array(); + + foreach($this->getJsonAttributes() as $jsonAttribute) + { + $jsonAttributes[$jsonAttribute] = dmArray::get($attributes, $jsonAttribute); + + unset($attributes[$jsonAttribute]); + } + + // ease unit tests + ksort($jsonAttributes); + + $attributes['class'][] = json_encode($jsonAttributes); + + return $attributes; + } + + protected function getJsonAttributes() + { + return array('address', 'coords', 'mapTypeId', 'zoom', 'navigationControl', 'mapTypeControl', 'scaleControl'); + } + + public function getJavascripts() + { + return array( + 'dmGoogleMapPlugin.dmGoogleMap', + 'dmGoogleMapPlugin.launcher' + ); + } + + public function getStylesheets() + { + return array(); + } +} \ No newline at end of file diff --git a/modules/dmWidgetGoogleMap/templates/_showForm.php b/modules/dmWidgetGoogleMap/templates/_showForm.php new file mode 100644 index 0000000..b2420b6 --- /dev/null +++ b/modules/dmWidgetGoogleMap/templates/_showForm.php @@ -0,0 +1,46 @@ +renderGlobalErrors(), + +_open('div.dm_tabbed_form'), + +_tag('ul.tabs', + _tag('li', _link('#'.$baseTabId.'_map')->text(__('Map'))). + _tag('li', _link('#'.$baseTabId.'_controls')->text(__('Controls'))). + _tag('li', _link('#'.$baseTabId.'_presentation')->text(__('Presentation'))) +), + +_tag('div#'.$baseTabId.'_map.drop_zone', + _tag('ul.dm_form_elements', + $form['address']->renderRow(). + $form['mapTypeId']->renderRow(). + $form['zoom']->renderRow() + ) +), + +_tag('div#'.$baseTabId.'_controls.drop_zone', + _tag('ul.dm_form_elements', + $form['navigationControl']->renderRow(). + $form['mapTypeControl']->renderRow(). + $form['scaleControl']->renderRow() + ) +), + +_tag('div#'.$baseTabId.'_presentation', + _tag('ul.dm_form_elements', + _tag('li.dm_form_element.multi_inputs.clearfix', + $form['width']->renderError(). + $form['height']->renderError(). + _tag('label', __('Dimensions')). + $form['width']->render(). + 'x'. + $form['height']->render() + ). + $form['splash']->renderRow(). + $form['cssClass']->renderRow() + ) +), + +_close('div'); //div.dm_tabbed_form \ No newline at end of file diff --git a/nbproject/private/config.properties b/nbproject/private/config.properties new file mode 100644 index 0000000..e69de29 diff --git a/nbproject/private/private.properties b/nbproject/private/private.properties new file mode 100644 index 0000000..0f22351 --- /dev/null +++ b/nbproject/private/private.properties @@ -0,0 +1,4 @@ +copy.src.files=false +copy.src.target= +index.file=index.php +url=http://localhost/dmGoogleMapPlugin/ diff --git a/nbproject/private/private.xml b/nbproject/private/private.xml new file mode 100644 index 0000000..c1f155a --- /dev/null +++ b/nbproject/private/private.xml @@ -0,0 +1,4 @@ + + + + diff --git a/nbproject/project.properties b/nbproject/project.properties new file mode 100644 index 0000000..f4bf301 --- /dev/null +++ b/nbproject/project.properties @@ -0,0 +1,10 @@ +file.reference.workspace-diem=../diem +include.path=\ + ${php.global.include.path}:\ + ${file.reference.workspace-diem} +php.version=PHP_5 +source.encoding=UTF-8 +src.dir=. +tags.asp=false +tags.short=true +web.root=. diff --git a/nbproject/project.xml b/nbproject/project.xml new file mode 100644 index 0000000..b8af541 --- /dev/null +++ b/nbproject/project.xml @@ -0,0 +1,9 @@ + + + org.netbeans.modules.php.project + + + dmGoogleMapPlugin + + + diff --git a/web/js/dmGoogleMap.js b/web/js/dmGoogleMap.js new file mode 100644 index 0000000..63fab31 --- /dev/null +++ b/web/js/dmGoogleMap.js @@ -0,0 +1,61 @@ +(function($) +{ + $.fn.dmGoogleMap = function(opt) + { + if(typeof google == "undefined" || typeof google.maps == "undefined") + { + alert('Please reload the page to activate the map'); + return this; + } + + var + self = this, + options = $.extend({ + zoom: 14, + mapTypeId: google.maps.MapTypeId.HYBRID + }, self.metadata(), opt || {}), + map, + marker; + + if(options.coords) + { + coords = new google.maps.LatLng(options.coords[0], options.coords[1]); + + map = new google.maps.Map(self.get(0), $.extend(options, { center: coords })); + marker = new google.maps.Marker({ + position: coords, + map: map + }); + } + else if(options.address) + { + geocoder = new google.maps.Geocoder(); + geocoder.geocode({ address: options.address }, function(results, status) + { + found = false; + + if (status == google.maps.GeocoderStatus.OK && results.length) + { + if (status != google.maps.GeocoderStatus.ZERO_RESULTS) + { + map = new google.maps.Map(self.get(0), $.extend(options, { center: results[0].geometry.location })); + + marker = new google.maps.Marker({ + position: results[0].geometry.location, + map: map + }); + + found = true; + } + } + + if(!found) + { + self.text('Sorry, the address "'+options.address+'" can not be found'); + } + }); + } + + return this; + } +})(jQuery); \ No newline at end of file diff --git a/web/js/launcher.js b/web/js/launcher.js new file mode 100644 index 0000000..37afb8e --- /dev/null +++ b/web/js/launcher.js @@ -0,0 +1,21 @@ +(function($) +{ + // front + $('#dm_page div.dm_widget').bind('dmWidgetLaunch', function() + { + var $map = $(this).find('.dm_google_map'); + + if($map.length) + { + setTimeout(function() {$map.dmGoogleMap();}, 1000); + } + }); + + // admin + $(function() { + $('#dm_admin_content .dm_google_map').each(function() { + $(this).dmGoogleMap(); + }); + }); + +})(jQuery); \ No newline at end of file diff --git a/web/js/widget/showForm.js b/web/js/widget/showForm.js new file mode 100644 index 0000000..813bb6f --- /dev/null +++ b/web/js/widget/showForm.js @@ -0,0 +1,9 @@ +$.fn.extend({ + + dmWidgetGoogleMapShowForm: function(widget) + { + var self = this, + $form = self.find('form:first'), + $tabs = $form.find('div.dm_tabbed_form').dmCoreTabForm(); + } +}); \ No newline at end of file