path . '/manage/%entity_object/export/svg'] = array(
'title' => 'Export to SVG',
'page callback' => 'jsmap_svgexport_callback',
'page arguments' => array($this->entityType, 4),
'access callback' => 'jsmap_map_access',
'access arguments' => array('export', array(4)),
'file' => 'jsmap_map.admin.inc',
'file path' => drupal_get_path('module', $this->entityInfo['module']),
'type' => MENU_CALLBACK,
);
$items[$this->path]['description'] = 'Manage maps, including adding
and removing fields and the display of fields.';
return $items;
}
/**
* Generates the render array for a overview table for arbitrary entities
* matching the given conditions.
*
* @param $conditions
* An array of conditions as needed by entity_load().
* @return Array
* A renderable array.
*/
public function overviewTable($conditions = array()) {
$entities = entity_load($this->entityType, FALSE, $conditions);
ksort($entities);
$rows = array();
foreach ($entities as $entity) {
$rows[] = $this->overviewTableRow($conditions, entity_id($this->entityType, $entity), $entity);
}
// Assemble the right table header.
$header = array(t('Label'));
if (!empty($this->entityInfo['exportable'])) {
$header[] = t('Status');
}
// Add operations with the right colspan.
$field_ui = !empty($this->entityInfo['bundle of']) && module_exists('field_ui');
$exportable = !empty($this->entityInfo['exportable']);
$colspan = 4;
$colspan = $field_ui ? $colspan + 2 : $colspan;
$colspan = $exportable ? $colspan + 1 : $colspan;
$header[] = array('data' => t('Operations'), 'colspan' => $colspan);
$render = array(
'#theme' => 'table',
'#header' => $header,
'#rows' => $rows,
'#empty' => t('None.'),
);
return $render;
}
/**
* Generates the row for the passed entity and may be overridden in order to
* customize the rows.
*
* @param $additional_cols
* Additional columns to be added after the entity label column.
*/
protected function overviewTableRow($conditions, $id, $entity, $additional_cols = array()) {
$entity_uri = entity_uri($this->entityType, $entity);
$row[] = array('data' => array(
'#theme' => 'entity_ui_overview_item',
'#label' => entity_label($this->entityType, $entity),
'#name' => !empty($this->entityInfo['exportable']) ? entity_id($this->entityType, $entity) : FALSE,
'#url' => $entity_uri ? $entity_uri : FALSE,
'#entity_type' => $this->entityType),
);
// Add in any passed additional cols.
foreach ($additional_cols as $col) {
$row[] = $col;
}
// Add a row for the exportable status.
if (!empty($this->entityInfo['exportable'])) {
$row[] = array('data' => array(
'#theme' => 'entity_status',
'#status' => $entity->{$this->statusKey},
));
}
// In case this is a bundle, we add links to the field ui tabs.
$field_ui = !empty($this->entityInfo['bundle of']) && module_exists('field_ui');
// For exportable entities we add an export link.
$exportable = !empty($this->entityInfo['exportable']);
$colspan = 4;
$colspan = $field_ui ? $colspan + 2 : $colspan;
$colspan = $exportable ? $colspan + 1 : $colspan;
// Add operations depending on the status.
if (entity_has_status($this->entityType, $entity, ENTITY_FIXED)) {
$row[] = array('data' => l(t('clone'), $this->path . '/manage/' . $id . '/clone'), 'colspan' => $colspan);
}
else {
$row[] = l(t('edit'), $this->path . '/manage/' . $id);
$row[] = l(t('edit regions'), $this->path . '/regions/' . $id);
if ($field_ui) {
$row[] = l(t('manage fields'), $this->path . '/manage/' . $id . '/fields');
$row[] = l(t('manage display'), $this->path . '/manage/' . $id . '/display');
}
$row[] = l(t('clone'), $this->path . '/manage/' . $id . '/clone');
if (empty($this->entityInfo['exportable']) || !entity_has_status($this->entityType, $entity, ENTITY_IN_CODE)) {
$row[] = l(t('delete'), $this->path . '/manage/' . $id . '/delete', array('query' => drupal_get_destination()));
}
elseif (entity_has_status($this->entityType, $entity, ENTITY_OVERRIDDEN)) {
$row[] = l(t('revert'), $this->path . '/manage/' . $id . '/revert', array('query' => drupal_get_destination()));
}
else {
$row[] = '';
}
}
if ($exportable) {
$row[] = l(t('export'), $this->path . '/manage/' . $id . '/export');
}
return $row;
}
/**
* Override the operation form.
*
* For the export operation a serialized string of the entity is directly
* shown in the form (no submit function needed).
*/
public function operationForm($form, &$form_state, $entity, $op) {
$form = parent::operationForm($form, $form_state, $entity, $op);
switch ($op) {
case 'import':
// Get maps and build select options
foreach (module_invoke_all('jsmap_mapfiles') as $map) {
$options[$map['category']][$map['filepath']] = $map['name'];
}
// Sort maps within each optgroup
foreach ($options as $category => &$items) {
asort($items);
}
// Add a "Select..." option
array_unshift($options, t('- None selected -'));
$form['map'] = array(
'#type' => 'fieldset',
'#weight' => -10,
);
$form['map']['filepath'] = array(
'#type' => 'select',
'#title' => t('Select a built-in map file'),
'#options' => $options,
);
$form['map']['or'] = array(
'#type' => 'markup',
'#markup' => '
'. t('Or') .'
',
);
$form['import']['#title'] = $form['import']['#description'];
unset($form['import']['#description']);
$form['map']['import'] = $form['import'];
unset($form['import']);
$form['label'] = array(
'#type' => 'textfield',
'#title' => t('Override the map name'),
'#description' => t('The human-readable name of this map. Leave blank to use the map\'s default name.'),
'#size' => 30,
'#weight' => -2,
);
$form['machine_name'] = array(
'#type' => 'machine_name',
'#title' => t('Override the machine name'),
'#maxlength' => 32,
'#description' => t('A unique machine name for this map. It must only contain lowercase letters, numbers, and underscores. Leave blank to use the map\'s default machine name.'),
'#required' => FALSE,
'#weight' => -1,
'#machine_name' => array(
'exists' => 'jsmap_get_maps',
'source' => array('label'),
),
);
return $form;
case 'export':
$form['exportsvg'] = array(
'#markup' => l('Export as SVG', $this->path .'/manage/'. $entity->map .'/export/svg')
);
case 'revert':
case 'delete':
return $form;
}
drupal_not_found();
exit;
}
/**
* Operation form validation callback.
*/
public function operationFormValidate($form, &$form_state) {
if ($form_state['op'] == 'import') {
$values = &$form_state['values'];
// Clean-up input
$values['label'] = trim($values['label']);
$values['machine_name'] = trim($values['machine_name']);
$values['import'] = trim($values['import']);
$jsmap = NULL;
// A file is selected and a map definition was pasted in.
if (!empty($values['filepath']) && !empty($values['import'])) {
form_set_error('map', t('Either select a built-in map file OR paste an exported map into the text box.'));
}
// No file is selected and nothing has been pasted in.
elseif (empty($values['filepath']) && empty($values['import'])) {
form_set_error('map', t('Select a built-in map or paste an exported map into the textarea to import.'));
}
// File is selected but cannot be found.
elseif (!empty($values['filepath']) && !file_exists($values['filepath'])) {
form_set_error('filepath', t('The selected map file (@file) could not be found.', array('@file' => $values['filepath'])));
}
// Get built-in map file
elseif (!empty($values['filepath'])) {
$jsmap = file_get_contents($values['filepath']);
}
// Get pasted in map definition
elseif (!empty($values['import'])) {
$jsmap = $values['import'];
}
// Override label / machine name
if ($jsmap) {
$jsmap = json_decode($jsmap);
// Override map label
if (!empty($values['label'])) {
$jsmap->label = $values['label'];
}
// Override machine_name
if (!empty($values['machine_name'])) {
$jsmap->map = $values['machine_name'];
foreach($jsmap->regions as &$region) {
$region->map = $values['machine_name'];
}
}
$jsmap = json_encode($jsmap);
}
// Attempt to import the map
if ($entity = entity_import($this->entityType, $jsmap)) {
// Store the successfully imported entity in $form_state.
$form_state[$this->entityType] = $entity;
if (!$form_state['values']['overwrite']) {
// Check for existing entities with the same identifier.
$id = entity_id($this->entityType, $entity);
$entities = entity_load($this->entityType, array($id));
if (!empty($entities)) {
$label = entity_label($this->entityType, $entity);
$vars = array('%entity' => $this->entityInfo['label'], '%label' => $label);
form_set_error('import', t('Import of %entity %label failed, a %entity with the same machine name already exists. Check the overwrite option to replace it.', $vars));
}
}
}
else {
form_set_error('', t('Import failed.'));
}
}
}
}
function jsmap_svgexport_callback($entity_type, $entity){
drupal_add_http_header("Content-disposition",'attachment; filename='. $entity->map .'.svg');
drupal_add_http_header('Content-Type', 'text/plain; utf-8');
print entity_get_controller($entity_type)->svgExport($entity);
}
/**
* Generates the map editing form.
*/
function jsmap_map_form($form, &$form_state, $map, $op = 'edit') {
if ($op == 'clone') {
$map->label .= ' (cloned)';
$map->map = '';
}
$form['label'] = array(
'#title' => t('Label'),
'#type' => 'textfield',
'#default_value' => $map->label,
'#description' => t('The human-readable name of this map.'),
'#required' => TRUE,
'#size' => 30,
);
// Machine-readable type name.
$form['map'] = array(
'#type' => 'machine_name',
'#default_value' => isset($map->map) ? $map->map : '',
'#maxlength' => 32,
'#machine_name' => array(
'exists' => 'jsmap_get_maps',
'source' => array('label'),
),
'#description' => t('A unique machine-readable name for this map. It must only contain lowercase letters, numbers, and underscores.'),
);
$form['actions'] = array('#type' => 'actions');
$form['actions']['submit'] = array(
'#type' => 'submit',
'#value' => t('Save map'),
'#weight' => 40,
);
return $form;
}
/**
* Form API submit callback for the type form.
*/
function jsmap_map_form_submit(&$form, &$form_state) {
$jsmap_map = entity_ui_form_submit_build_entity($form, $form_state);
$jsmap_map->save();
$form_state['redirect'] = 'admin/structure/jsmap_maps';
}
/**
* Form API submit callback for the delete button.
*/
function jsmap_map_form_submit_delete(&$form, &$form_state) {
$form_state['redirect'] = 'admin/structure/jsmap_maps/manage/' . $form_state['jsmap_map']->map . '/delete';
}
/**
* Implements hook_jsmap_mapfiles().
*/
function jsmap_jsmap_mapfiles() {
$basepath = drupal_get_path('module', 'jsmap') .'/maps';
return array(
array(
'filepath' => $basepath .'/world/world_map.jsmap',
'category' => t('World Maps'),
'name' => t('Basic world map'),
),
array(
'filepath' => $basepath .'/country/cn.jsmap',
'category' => t('Country Maps'),
'name' => t('China'),
)
);
}