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'), ) ); }