You are here

function yamaps_field_formatter_view in Yandex.Maps 7

Implements hook_field_formatter_view().

File

inc/yamaps.formatter.inc, line 490
Yandex Maps field formatter.

Code

function yamaps_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
  if (empty($items)) {
    return [];
  }
  $element = [];
  $settings = $display['settings'];
  $entity_info = entity_get_info($entity_type);
  $entity_id = uniqid();
  if (isset($entity_info['entity keys']['id']) && isset($entity->{$entity_info['entity keys']['id']})) {
    $entity_id = $entity->{$entity_info['entity keys']['id']};
  }
  switch ($display['type']) {
    case YAMAPS_DYNAMIC_FORMATTER:
      $maps = [];
      foreach ($items as $delta => $item) {

        // Ensure that field with empty coordinates doesn't show up.
        if (empty($item['coords']) || $item['hide'] == 1) {
          continue;
        }

        // Map id.
        $id = drupal_html_id(implode('-', [
          'ymap',
          $entity_type,
          $entity_id,
          $field['field_name'],
          $delta,
        ]));

        // Unique map button id.
        $open_button_id = drupal_html_id(implode('-', [
          $id,
          'open_button',
        ]));
        $close_button_id = drupal_html_id(implode('-', [
          $id,
          'close_button',
        ]));

        // Coordinates of map center.
        $coords = drupal_json_decode($item['coords']);
        if (isset($settings['yamaps_display_options']['display_type']) && $settings['yamaps_display_options']['display_type'] == 'map_button') {
          $element[$delta]['open_button_text'] = [
            '#type' => 'html_tag',
            '#tag' => 'div',
            '#value' => isset($settings['yamaps_display_options']['open_button_text']) ? t($settings['yamaps_display_options']['open_button_text']) : t(YAMAPS_DEFAULT_OPEN_MAP_TEXT),
            '#attributes' => [
              'id' => $open_button_id,
              'class' => [
                'open_yamap_button',
              ],
              'mapId' => $id,
            ],
          ];
          $element[$delta]['close_button_text'] = [
            '#type' => 'html_tag',
            '#tag' => 'div',
            '#value' => isset($settings['yamaps_display_options']['close_button_text']) ? t($settings['yamaps_display_options']['close_button_text']) : t(YAMAPS_DEFAULT_CLOSE_MAP_TEXT),
            '#attributes' => [
              'id' => $close_button_id,
              'class' => [
                'close_yamap_button',
                'element-invisible',
              ],
              'mapId' => $id,
            ],
          ];
        }
        $hide_map = isset($settings['yamaps_display_options']['display_type']) && $settings['yamaps_display_options']['display_type'] == 'map_button';
        $map_class = [
          'yamaps-map-container',
        ];
        $map_class[] = $hide_map ? 'element-invisible' : '';

        // Return map container div.
        $element[$delta]['map_container'] = [
          '#type' => 'html_tag',
          '#tag' => 'div',
          '#attributes' => [
            'id' => $id,
            'style' => 'width:' . $settings['width'] . '; height:' . $settings['height'] . ';',
            'class' => $map_class,
          ],
          '#value' => '',
        ];

        // Map initialization parameters.
        $maps[$id] = [
          'init' => [
            'center' => $coords['center'],
            'zoom' => $coords['zoom'],
            'type' => $item['type'] ? $item['type'] : 'yandex#map',
            'behaviors' => array_values(array_filter($settings['behaviors'])),
          ],
          'display_options' => [
            'display_type' => $settings['yamaps_display_options']['display_type'],
          ],
          'controls' => isset($settings['controls']) ? $settings['controls'] : NULL,
          'traffic' => isset($settings['traffic']) ? $settings['traffic'] : NULL,
          'clusterer' => isset($settings['clusterer']) ? $settings['clusterer'] : NULL,
          'auto_zoom' => isset($settings['auto_zoom']) ? $settings['auto_zoom'] : NULL,
          'enable_polygons' => isset($settings['enable_polygons']) ? $settings['enable_polygons'] : NULL,
          'enable_lines' => isset($settings['enable_lines']) ? $settings['enable_lines'] : NULL,
          'enable_placemarks' => isset($settings['enable_placemarks']) ? $settings['enable_placemarks'] : NULL,
          'enable_routes' => isset($settings['enable_routes']) ? $settings['enable_routes'] : NULL,
          'placemarks' => drupal_json_decode($item['placemarks']),
          'lines' => drupal_json_decode($item['lines']),
          'polygons' => drupal_json_decode($item['polygons']),
          'routes' => drupal_json_decode($item['routes']),
          'edit' => FALSE,
        ];
      }

      // Adding map to js and load library.
      $element['#attached']['js'][] = [
        'data' => [
          'yamaps' => $maps,
        ],
        'type' => 'setting',
      ];
      $element['#attached']['library'][] = [
        'yamaps',
        'yamaps.full',
      ];

      // Fixing formatter rendered by Views module (display and preview modes).
      $element[$delta]['#attached']['js'] = $element['#attached']['js'];
      $element[$delta]['#attached']['library'] = $element['#attached']['library'];
      break;
    case YAMAPS_STATIC_FORMATTER:
      foreach ($items as $delta => $item) {

        // Ensure that field with empty coordinates doesn't show up.
        if (empty($item['coords']) || $item['hide'] == 1) {
          continue;
        }
        $coords = drupal_json_decode($item['coords']);
        $params = [];
        $params['ll'] = end($coords['center']) . ',' . reset($coords['center']);
        $params['z'] = $coords['zoom'];
        $params['size'] = $settings['s_width'] . ',' . $settings['s_height'];

        // 2.x to 1.x types.
        $map_types = [
          'yandex#map' => 'map',
          'yandex#satellite' => 'sat',
          'yandex#hybrid' => 'sat,skl',
          'yandex#publicMap' => 'pmap',
          'yandex#publicMapHybrid' => 'sat,pskl',
        ];
        $params['l'] = $map_types[$item['type'] ? $item['type'] : 'yandex#map'];
        if ($settings['s_traffic']) {
          $params['l'] .= ',trf';
        }

        // 2.x to 1.x colors.
        $colors21 = [
          'blue' => 'bl',
          'lightblue' => 'lb',
          'night' => 'nt',
          'darkblue' => 'db',
          'green' => 'gn',
          'white' => 'wt',
          'red' => 'rd',
          'orange' => 'or',
          'darkorange' => 'do',
          'yellow' => 'yw',
          'violet' => 'vv',
          'pink' => 'pn',
        ];

        // 2.x to hex colors.
        $colors = yamaps_get_colors();

        // Placemarks.
        if ($item['placemarks']) {
          $pt = [];
          foreach (drupal_json_decode($item['placemarks']) as $placemark) {
            $pm = end($placemark['coords']) . ',' . reset($placemark['coords']) . ',';
            $pm .= 'pm2';
            $pm .= $colors21[$placemark['params']['color']];
            $pm .= 'm';
            $pt[] = $pm;
          }
          $params['pt'] = implode('~', $pt);
        }

        // Lines and polygons.
        $pl = [];
        if ($item['lines']) {
          foreach (drupal_json_decode($item['lines']) as $line) {
            $opts = $line['params'];
            $pm = 'c:' . $colors[$opts['strokeColor']] . dechex(255 * $opts['opacity']) . ',';
            $pm .= 'w:' . $opts['strokeWidth'] . ',';
            $c = [];
            foreach ($line['coords'] as $coords) {
              $c[] = end($coords);
              $c[] = reset($coords);
            }
            $pm .= implode(',', $c);
            $pl[] = $pm;
          }
        }
        if ($item['polygons']) {
          foreach (drupal_json_decode($item['polygons']) as $polygon) {
            $opts = $polygon['params'];
            $opa = dechex(255 * $opts['opacity']);
            $pm = 'c:' . $colors[$opts['strokeColor']] . $opa . ',';
            $pm .= 'f:' . $colors[$opts['fillColor']] . $opa . ',';
            $pm .= 'w:' . $opts['strokeWidth'] . ',';
            $c = [];
            foreach ($polygon['coords'] as $coords_array) {
              foreach ($coords_array as $coords) {
                $c[] = end($coords);
                $c[] = reset($coords);
              }
            }
            $pm .= implode(',', $c);
            $pl[] = $pm;
          }
        }
        if (!empty($pl)) {
          $params['pl'] = implode('~', $pl);
        }

        // Map id and parameters.
        $id = drupal_html_id(implode('-', [
          'ymap',
          $entity->type,
          $entity_id,
          $field['field_name'],
          $delta,
        ]));
        $open_button_id = drupal_html_id(implode('-', [
          $id,
          'open_button',
        ]));
        $close_button_id = drupal_html_id(implode('-', [
          $id,
          'close_button',
        ]));
        $hide_map = isset($settings['yamaps_display_options_static']['display_type_static']) && $settings['yamaps_display_options_static']['display_type_static'] == 'map_button';
        $map_class = $hide_map ? 'element-invisible' : '';
        if ($hide_map) {
          $element[$delta]['open_button_text'] = [
            '#type' => 'html_tag',
            '#tag' => 'div',
            '#value' => isset($settings['yamaps_display_options_static']['open_button_text_static']) ? t($settings['yamaps_display_options_static']['open_button_text_static']) : t(YAMAPS_DEFAULT_OPEN_MAP_TEXT),
            '#attributes' => [
              'id' => $open_button_id,
              'class' => [
                'open_yamap_button',
              ],
              'mapId' => $id,
            ],
          ];
          $element[$delta]['close_button_text'] = [
            '#type' => 'html_tag',
            '#tag' => 'div',
            '#value' => isset($settings['yamaps_display_options_static']['close_button_text_static']) ? t($settings['yamaps_display_options_static']['close_button_text_static']) : t(YAMAPS_DEFAULT_CLOSE_MAP_TEXT),
            '#attributes' => [
              'id' => $close_button_id,
              'class' => [
                'close_yamap_button',
                'element-invisible',
              ],
              'mapId' => $id,
            ],
          ];
        }

        // Return map container div with image.
        $element[$delta]['map_container'] = [
          '#type' => 'html_tag',
          '#tag' => 'div',
          '#attributes' => [
            'id' => $id,
            'style' => 'width:' . $settings['s_width'] . 'px; height:' . $settings['s_height'] . 'px;',
            'class' => [
              $map_class,
            ],
          ],
          '#value' => theme('image', [
            'path' => url(YAMAPS_STATIC_API_URL, [
              'query' => $params,
              'external' => TRUE,
            ]),
            'width' => $settings['s_width'],
            'height' => $settings['s_height'],
            'title' => t('Yandex Map'),
          ]),
        ];

        // Map initialization parameters.
        $maps[$id] = [
          'display_options' => [
            'display_type' => $settings['yamaps_display_options_static']['display_type_static'],
          ],
        ];

        // Adding CSS for button.
        $element[$delta]['map_container']['#attached']['css'][] = drupal_get_path('module', 'yamaps') . '/misc/yamaps.css';

        // Adding map to js and load library.
        $element[$delta]['map_container']['#attached']['js'][] = [
          'data' => [
            'yamapsStatic' => $maps,
          ],
          'type' => 'setting',
        ];
        $element[$delta]['map_container']['#attached']['library'][] = [
          'yamaps',
          'yamaps.full',
        ];
      }
      break;
    case YAMAPS_TEXT_FORMATTER:
      $display_options = variable_get('yamaps_block_edit_display_options', []);
      $active_behaviors = array_values(array_filter($settings['behaviors']));

      // This options must be defined to avoid problems on map rendering.
      $width = !empty($settings['width']) ? $settings['width'] : '100%';
      $height = !empty($settings['height']) ? $settings['height'] : '400px';
      foreach ($items as $delta => $item) {
        $id = drupal_html_id('yamap-text');
        $element[$delta]['container'] = [
          '#type' => 'html_tag',
          '#tag' => 'div',
          '#attributes' => [
            'id' => $id,
            'style' => "width: {$width}; height: {$height};",
            'class' => [
              'yamaps-map-text-container',
            ],
            'data-address' => $item['safe_value'],
          ],
          '#value' => '',
          '#attached' => [
            'js' => [
              drupal_get_path('module', 'yamaps') . '/misc/yamaps.text.js',
              [
                'type' => 'setting',
                'data' => [
                  'yamapsGeocoderUrl' => YAMAPS_GEOCODER_URL . '?format=json&results=1',
                  'yamaps-row' => [
                    $id => [
                      'init' => [
                        // We will fill this one via JS.
                        'center' => [],
                        'behaviors' => $active_behaviors,
                        'type' => 'yandex#map',
                      ],
                      'controls' => (bool) $settings['control'],
                      'traffic' => (bool) $settings['traffic'],
                      'clusterer' => (bool) $settings['clusterer'],
                      'auto_zoom' => (bool) $settings['auto_zoom'],
                      'enable_polygons' => $settings['enable_polygons'],
                      'enable_lines' => $settings['enable_lines'],
                      'enable_placemarks' => $settings['enable_placemarks'],
                      'enable_routes' => $settings['enable_routes'],
                      'display_options' => [
                        'display_type' => isset($display_options['display_type']) ? $display_options['display_type'] : 'map',
                      ],
                      /**
                       * Placemarks will be filled later after settings checking.
                       * We need an empty array here because it could be not
                       * filled later to avoid one more "if" in JS.
                       */
                      'placemarks' => [],
                      'edit' => FALSE,
                      'lines' => NULL,
                      'polygons' => NULL,
                      'routes' => NULL,
                    ],
                  ],
                  'yamaps' => [],
                ],
              ],
            ],
          ],
        ];
        $element[$delta]['container']['#attached']['library'][] = [
          'yamaps',
          'yamaps.full',
        ];

        // Check if we should display placemark.
        if ($settings['placemark']['placemark_display']) {
          if (!empty($settings['placemark']['placemark_text'])) {
            $settings['placemark']['placemark_text'] = str_replace('[address]', $item['safe_value'], $settings['placemark']['placemark_text']);
          }

          // Add placemark information.
          $element[$delta]['container']['#attached']['js'][1]['data']['yamaps-row'][$id]['placemarks'][] = [
            // We will full this field via JS.
            'coords' => [],
            'params' => [
              // Placemark color.
              'color' => $settings['placemark']['placemark_color'],
              // Placemark text.
              'iconContent' => $settings['placemark']['placemark_text'],
            ],
          ];
        }
      }
      break;
  }
  return $element;
}