< New Plugins

Using the Security Infrastructure >

## 3. Dynamic mapfile modifications

## 3.1. Introduction

This chapter describes the mapOverlay plugin. This plugin allows dynamic modifications of the mapfile, it can be used for example to: let the user add a WMS layer, restrict data to be exported to the user, change the color of layers, etc ...

The plugin has only a server part and only a public method:

    public function updateMap(BasicOverlay $overlay)

The `$overlay` argument is either a `MapOverlay` or a `LayerOverlay` instance, it represent respectively a mapfile or a layer.

Customizable elements are:

- `ColorOverlay`
- `StyleOverlay`
- `LabelOverlay`
- `ClassOverlay`
- `MetadataOverlay`
- `LayerOverlay`
- `MapOverlay`

The organization of these elements are the same as the mapfile structure: a `MapOverlay` contains zero or many `LayerOverlay` who cantains zero or many `MetadataOverlay` etc. None of theses elements or instance variables are mandatory, you just need to provide informations about property you want to search, update, insert or delete.

For each of theses mapfile elements the developer have to provide an action by setting the `action` instance variable. The action set the behavior of the element during the mapfile update process. `action` is one of:

- `BasicOverlay::ACTION_SEARCH`: this action search or create the element.
- `BasicOverlay::ACTION_INSERT`: insert the element at a given position or at the end if not specified.
- `BasicOverlay::ACTION_REMOVE`: remove the element.
- `BasicOverlay::ACTION_UPDATE`: update or create the element.

If no action is specified, the default action is `BasicOverlay::ACTION_UPDATE`.

The standards steps to use this mechanism are:

1. Create all the needed elements and combine them together in a `MapOverlay` or a `LayerOverlay` instance.
2. Call the `updateMap()` function. The function returns a `MapOverlay` instance.
3. If needed, use the result instance to retrieve an index or a element name.

Note that the modification are not saved in the project's mapfile: the result of the mapfile modifications are specific to a session.

## 3.2. Plugin usage

This chapter contains some basic examples of the plugin usage. All the code listed here must be placed in the server part of a plugin.

### 3.2.1. Class creation

Consider this code excerpt:

    $color = new ColorOverlay();
    $color->red = 255;
    $color->green = 0;
    $color->blue = 0;

    $style = new StyleOverlay();
    $style->index = 0;
    $style->color = $color;

    $label = new LabelOverlay();
    $label->outlineColor = $color;

    $class = new ClassOverlay();
    $class->action = BasicOverlay::ACTION_INSERT;
    $class->name = 'foobar';
    $class->styles = array($style);
    $class->label = $label;

A `ColorOverlay` and a `StyleOverlay` are created. Create a `LabelOverlay` and set the text color. Note that those three instances ($color, $style and $label) have only a subset of theirs variable who are set.

    $layer1 = new LayerOverlay();
    $layer1->name = 'cartoweb_point_outline';
    $layer1->classes = array($class);

Put the class in the layer. The behavior of `$layer1` can be resumed as: Update or create a layer named 'cartoweb_point_outline'. In this layer, insert a new class an call it 'foobar', the first style of this class render as red.

    $layer2 = new LayerOverlay();
    $layer2->action = BasicOverlay::ACTION_SEARCH;
    $layer2->name = 'cartoweb_point_outline';
    $layer2->transparency = 30;

Search a layer named 'point_point_outline' with a 30% transparency. If this layer don't exist in the mapfile it will be created

    $map = new MapOverlay();
    $map->layers = array($layer1, $layer2);

    $plugins = $this->serverContext->getPluginManager();
    $result = $plugins->mapOverlay->updateMap($map);

The two layers are inserted in a `MapOverlay` and the mapfile is updated.

### 3.2.2. Add a feature

The goal of this example is to add a feature with a specific style and transparency. The layer name and transparency are given ('foo' and 40%).

    $layer = new LayerOverlay();
    $layer->name = 'foo';
    $layer->action = BasicOverlay::ACTION_SEARCH;
    $layer->transparency = 40;

    $mapOverlay = $this->serverContext->getPluginManager()->mapOverlay;
    $result = $mapOverlay->updateMap($layer);

At this point, the layer and its classes are created or updated. Now we need to insert the feature:

    $f = ms_newShapeObj(MS_SHAPE_POINT);
    $p->addXY(30000, 20000);
    $f->set('classindex', $result->layers[0]->classes[0]->index);

A `ms_newShapeObj` is created and the class index is fetched from the `updateMap()` return instance.

    $msLayer = $this->serverContext->getMapObj()->getLayer($result->layers[0]->index);
    $msLayer->addFeature($f);
    $msLayer->set('status', MS_ON);

This example also show that you can mix standard phpMapscript and mapOverlay code.

### 3.2.3. Filter data

    $layer = new LayerOverlay();
    $layer->name = "field";
    $layer->data = "geom FROM (SELECT gid, geom, name FROM fields WHERE farm_id = {$farmId}) " .
                   "AS foo USING UNIQUE gid USING SRID=-1";

    $mapOverlay = $this->serverContext->getPluginManager()->mapOverlay;
    $mapOverlay->updateMap($layer);

The `DATA` field of the `field` layer is update to only display some informations. `$farmId` is defined elsewhere.

In this case, a much more clever solution is to use the `filter` attribute of the `LayerOverlay` object.

    $layer = new LayerOverlay();
    $layer->name = "field";
    $layer->filter = "farm_id = {$farmId})";

    $mapOverlay = $this->serverContext->getPluginManager()->mapOverlay;
    $mapOverlay->updateMap($layer);

### 3.2.4. Debugging

At any time you can see the result of the modifications by calling:

    $this->serverContext->getMapObj()->save('/tmp/debug.map');

This will save the updated mapfile to `/tmp/debug.map`.