Completed
Push — master ( a56ece...37dc46 )
by Luis
05:29 queued 01:49
created

OpenLayers   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 96
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 7

Importance

Changes 16
Bugs 2 Features 5
Metric Value
wmc 14
c 16
b 2
f 5
lcom 1
cbo 7
dl 0
loc 96
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A init() 0 9 2
A run() 0 17 4
A processMapOptions() 0 10 4
A processSimplifiedLayers() 0 15 4
1
<?php
2
namespace sibilino\yii2\openlayers;
3
4
use yii\base\Widget;
5
use yii\helpers\Html;
6
use yii\helpers\Json;
7
8
/**
9
 * Yii 2 widget encapsulating OpenLayers 3 and offering simplified option specification.
10
 * @link https://github.com/Sibilino/yii2-openlayers
11
 * @copyright Copyright (c) 2015 Luis Hernández Hernández
12
 * @license http://opensource.org/licenses/MIT MIT
13
 */
14
class OpenLayers extends Widget
15
{
16
	/**
17
     * @var array the HTML attributes for the container div of this widget.
18
     * @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
19
     */
20
	public $options = [];
21
	/**
22
	 * The properties to be passed to the OpenLayers Map() constructor. In order to ease passing complex JavaScript structures, some simplifications are supported.
23
	 * See {@link OpenLayers::processMapOptions} for details on simplified option specification.
24
	 * @var array
25
	 */
26
	public $mapOptions = [];
27
    /**
28
     * The scripts that operate with the olwidget.js module, e. g. to apply map configuration in plain JavaScript.
29
     * Can be array to register multiple scripts. If the array is given string keys, they will be passed to [[yii\web\View::registerJsFile()]].
30
     * @var string|array
31
     */
32
    public $mapOptionScript = [];
33
34
	public function init()
35
	{
36
		if (!isset($this->options['id'])) {
37
			$this->options['id'] = $this->getId();
38
		}
39
		$this->mapOptions['target'] = $this->options['id'];
40
		OpenLayersBundle::register($this->view);
41
        OLModuleBundle::register($this->view);
42
	}
43
	
44
	public function run()
45
	{
46
		$this->processMapOptions();
47
48
        $scripts = is_array($this->mapOptionScript) ? $this->mapOptionScript : [$this->mapOptionScript];
49
        foreach ($scripts as $key => $script) {
50
            if (!is_string($key)) {
51
                $key = null; // Dont specify a key for non-associative array of scripts
52
            }
53
            $this->view->registerJsFile($script, ['depends'=>OLModuleBundle::className()], $key);
54
        }
55
        
56
        $script = 'sibilino.olwidget.createMap('.Json::encode($this->mapOptions).', "'.$this->options['id'].'")';
57
		$this->view->registerJs($script);
58
		
59
		return Html::tag('div', '', $this->options);
60
	}
61
	
62
	/**
63
	 * Checks whether several "complex" options have been specified as a key => value pair where key is a string.
64
	 * If found, those properies will be automatically turned into the JavaScript expression that instantiates the corresponding OpenLayers object, thus eliminating the need to manually create a JsExpression object.
65
	 * The value for these processed keys will be passed as options to the constructor of the OpenLayers object.
66
	 * Supported simplified properties are:
67
	 * <ul>
68
	 * <li><b>view</b>: Can be specified as 'view' => $optionArray.
69
	 * For example, <code>['view' => ['center'=>[0,0],'zoom'=>2]]</code> will produce this JS: <code>new ol.View({"center":[0,0], "zoom":2})</code>
70
	 * <li><b>layers</b>: Each layer in the array can be specified as $type => $options, where $type is a string.
71
	 * For example, <code>['layers' => ['Tile' => ['visible' => false]</code> will produce this JS: <code>new ol.layer.Tile({"visible": false})</code>
72
	 * <li><b>layer sources</b>: In addition, when a layer's $type => $option pair are both strings, the $option is considered the layer's "source", and will also be converted to the corresponding object.
73
	 * For example, <code>['layers' => ['Tile' => 'OSM']</code> will produce this JS: <code>new ol.layer.Tile({"source": new ol.source.OSM()})</code>
74
	 * </li>
75
	 * </ul>
76
	 * If these simplifications are not enough to avoid using complex JsExpression structures, make sure to see the {@link OL} class for an abbreviated way of specifying OpenLayers object instances.
77
	 * @see OL
78
	 */
79
	protected function processMapOptions()
80
	{
81
		if (isset($this->mapOptions['view']) && is_array($this->mapOptions['view'])) {
82
			$this->mapOptions['view'] = new OL('View', $this->mapOptions['view']);
83
		}
84
		
85
		if (isset($this->mapOptions['layers'])) {
86
			$this->processSimplifiedLayers();
87
		}
88
	}
89
	
90
	/**
91
	 * Takes each key => value pair in $this->mapOptions['layers'] and checks if key is a string. In that case, a new Layer OL object will created for this layer.
92
	 * Then, if the value is also a string, the corresponding Source OL object is created as well. 
93
	 */
94
	protected function processSimplifiedLayers()
95
	{
96
		$processedLayers = [];
97
		foreach ($this->mapOptions['layers'] as $type => $options) {
98
			if (is_string($type)) {
99
				if (is_string($options)) {
100
                    $options = ['source' => new OL("source.$options")];
101
                }
102
				$processedLayers []= new OL("layer.$type", $options);
103
			} else { // Therefore $type is simply an integer array key
104
                $processedLayers []= $options;
105
            }
106
		}
107
		$this->mapOptions['layers'] = $processedLayers;
108
	}
109
}
110