danielebarchiesi@4: 'vertical_tabs', danielebarchiesi@4: ); danielebarchiesi@4: danielebarchiesi@4: // Create a tab for each entity. danielebarchiesi@4: foreach ($entities as $entity_type => $entity) { danielebarchiesi@4: $render['tabs'][$entity_type] = array( danielebarchiesi@4: '#type' => 'fieldset', danielebarchiesi@4: '#title' => $entity['label'], danielebarchiesi@4: '#collapsible' => TRUE, danielebarchiesi@4: '#collapsed' => TRUE, danielebarchiesi@4: ); danielebarchiesi@4: // The bundle's RDF mapping array may contain mappings for entity attributes danielebarchiesi@4: // that are not fields. The bundle's field array may contain fields that are danielebarchiesi@4: // not in the RDF mapping array. In order to ensure we get all the available danielebarchiesi@4: // fields and all the mapped entity attributes, we compare the arrays. danielebarchiesi@4: foreach ($entity['bundles'] as $bundle_name => $bundle) { danielebarchiesi@4: $rows = array(); danielebarchiesi@4: $real_fields = array(); danielebarchiesi@4: $fake_fields = array(); danielebarchiesi@4: $bundle_fields = $fields[$entity_type][$bundle_name]; danielebarchiesi@4: $bundle['edit_path'] = NULL; danielebarchiesi@4: $rdf_mapping = $bundle['rdf_mapping']; danielebarchiesi@4: if (isset($bundle['admin']['real path'])) { danielebarchiesi@4: $bundle['edit_path'] = $bundle['admin']['real path'] . '/rdf'; danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: // Set RDF type. danielebarchiesi@4: if (isset($rdf_mapping['rdftype'])) { danielebarchiesi@4: $rdftype = implode(', ', $rdf_mapping['rdftype']); danielebarchiesi@4: unset($rdf_mapping['rdftype']); danielebarchiesi@4: } danielebarchiesi@4: foreach ($rdf_mapping as $field_name => $mapping_info) { danielebarchiesi@4: // Gather Field API fields. danielebarchiesi@4: if (isset($bundle_fields[$field_name])) { danielebarchiesi@4: $real_fields[$field_name]['rdf_mapping'] = $mapping_info; danielebarchiesi@4: $real_fields[$field_name]['label'] = $fields[$entity_type][$bundle_name][$field_name]['label']; danielebarchiesi@4: $real_fields[$field_name]['edit_path'] = $bundle['edit_path']; danielebarchiesi@4: unset($bundle_fields[$field_name]); danielebarchiesi@4: } danielebarchiesi@4: // Gather non-field content variables. danielebarchiesi@4: else { danielebarchiesi@4: $fake_fields[$field_name]['rdf_mapping'] = $mapping_info; danielebarchiesi@4: $fake_fields[$field_name]['label'] = $field_name; danielebarchiesi@4: $fake_fields[$field_name]['edit_path'] = ($field_name == 'title') ? $bundle['edit_path'] : NULL; danielebarchiesi@4: } danielebarchiesi@4: } danielebarchiesi@4: // Theme this bundle's table and add it to it's parent entity's tab. danielebarchiesi@4: $variables = array( danielebarchiesi@4: 'bundle' => $bundle, danielebarchiesi@4: 'rdftype' => $rdftype, danielebarchiesi@4: 'real_fields' => $real_fields, danielebarchiesi@4: 'fake_fields' => $fake_fields, danielebarchiesi@4: ); danielebarchiesi@4: $render['tabs'][$entity_type][$bundle_name] = theme('rdfx_mapping_admin_overview', $variables); danielebarchiesi@4: } danielebarchiesi@4: } danielebarchiesi@4: return $render; danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /** danielebarchiesi@4: * Theme function to output the table for a bundle's mappings. danielebarchiesi@4: */ danielebarchiesi@4: function theme_rdfx_mapping_admin_overview($variables) { danielebarchiesi@4: $bundle_label = $variables['bundle']['label']; danielebarchiesi@4: $bundle = $variables['bundle']; danielebarchiesi@4: $real_fields = $variables['real_fields']; danielebarchiesi@4: $fake_fields = $variables['fake_fields']; danielebarchiesi@4: $rows = array(); danielebarchiesi@4: danielebarchiesi@4: // Add the table header for this bundle. danielebarchiesi@4: $header = array(t('Fields'), t('RDF predicates'), t('Mapping type'), t('Datatype')); danielebarchiesi@4: if (module_exists('rdfui')) { danielebarchiesi@4: $header[] = t('Operations'); danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: // Display a title for each bundle above the mappings table. If RDF UI is danielebarchiesi@4: // enabled, also add an 'edit' link. danielebarchiesi@4: $title = "
" . t('RDF Types:') . ' ' . $variables['rdftype'] . $edit_link . '
'; danielebarchiesi@4: danielebarchiesi@4: // List all of the Field API fields and their mappings. danielebarchiesi@4: foreach ($real_fields as $name => $field) { danielebarchiesi@4: $rows[] = array( danielebarchiesi@4: 'data' => theme('rdfx_mapping_admin_overview_row', array('field' => $field, 'field_name' => $name, 'edit_path' => $field['edit_path'])), danielebarchiesi@4: ); danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: // Add any non-Field API entity attributes. danielebarchiesi@4: foreach ($fake_fields as $name => $field) { danielebarchiesi@4: $rows[] = array( danielebarchiesi@4: 'data' => theme('rdfx_mapping_admin_overview_row', array('field' => $field, 'field_name' => $name, 'edit_path' => $field['edit_path'])), danielebarchiesi@4: ); danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: // If there are no mappings, display a message inside the table. danielebarchiesi@4: if (!count($rows)) { danielebarchiesi@4: $rows[] = array( danielebarchiesi@4: 'data' => array(array('data' => t('No mappings have been configured for this bundle.'), 'colspan' => 5)) danielebarchiesi@4: ); danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: // Return the table for this bundle. danielebarchiesi@4: return array( danielebarchiesi@4: '#prefix' => $title, danielebarchiesi@4: '#theme' => 'table', danielebarchiesi@4: '#rows' => $rows, danielebarchiesi@4: '#header' => $header, danielebarchiesi@4: ); danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /** danielebarchiesi@4: * Theme function to output a field's row in the bundle mapping table. danielebarchiesi@4: */ danielebarchiesi@4: function theme_rdfx_mapping_admin_overview_row($variables) { danielebarchiesi@4: $field = $variables['field']; danielebarchiesi@4: danielebarchiesi@4: $field_label = '' . t($field['label']) . ''; danielebarchiesi@4: $predicates = isset($field['rdf_mapping']['predicates']) ? t(implode(', ', $field['rdf_mapping']['predicates'])) : ''; danielebarchiesi@4: $predicate_type = isset($field['rdf_mapping']['type']) ? check_plain($field['rdf_mapping']['type']) : 'property'; danielebarchiesi@4: $datatype = isset($field['rdf_mapping']['datatype']) ? $field['rdf_mapping']['datatype'] : ''; danielebarchiesi@4: danielebarchiesi@4: $row = array($field_label, $predicates, $predicate_type, $datatype); danielebarchiesi@4: danielebarchiesi@4: // Add operations links only if RDF UI is enabled. danielebarchiesi@4: if (module_exists('rdfui')) { danielebarchiesi@4: $operations = ''; danielebarchiesi@4: if (isset($variables['edit_path'])) { danielebarchiesi@4: // By adding the appropriate url fragment, we can open the corresponding danielebarchiesi@4: // vertical tab on the RDF mapping UI page. The fragment should correspond danielebarchiesi@4: // to the html id for each fieldset, which means certain characters need danielebarchiesi@4: // to be replaced. These replacement patterns are from drupal_html_id(). danielebarchiesi@4: $id = ($variables['field_name'] == 'title') ? 'rdf-title' : $variables['field_name']; danielebarchiesi@4: $id = strtr(drupal_strtolower($id), array(' ' => '-', '_' => '-', '[' => '-', ']' => '')); danielebarchiesi@4: $id = preg_replace('/[^A-Za-z0-9\-_]/', '', $id); danielebarchiesi@4: $id = preg_replace('/\-+/', '-', $id); danielebarchiesi@4: $operations = l(t('edit'), $variables['edit_path'], array('fragment' => "edit-$id")); danielebarchiesi@4: } danielebarchiesi@4: $row[] = $operations; danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: return $row; danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /** danielebarchiesi@4: * Menu callback for viewing all declared namespaces (conflicting and non-conflicting) danielebarchiesi@4: * and their prefixes. danielebarchiesi@4: */ danielebarchiesi@4: function rdfx_admin_namespaces() { danielebarchiesi@4: $output = ''; danielebarchiesi@4: danielebarchiesi@4: // List conflicting namespaces. danielebarchiesi@4: $conflicting_namespaces = rdfx_get_conflicting_namespaces(); danielebarchiesi@4: if ($conflicting_namespaces) { danielebarchiesi@4: $table_conflicting_namespaces = array(); danielebarchiesi@4: $table_conflicting_namespaces['header'] = array('Prefix', 'Conflicting Namespaces'); danielebarchiesi@4: foreach ($conflicting_namespaces as $prefix => $uris) { danielebarchiesi@4: $table_conflicting_namespaces['rows'][] = array($prefix, implode(", ", $uris)); danielebarchiesi@4: } danielebarchiesi@4: $output .= ' '; danielebarchiesi@4: $output .= theme('table', $table_conflicting_namespaces); danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: // List non-conflicting namespaces. danielebarchiesi@4: $table_namespaces = array(); danielebarchiesi@4: $table_namespaces['header'] = array('Prefix', 'Namespace'); danielebarchiesi@4: foreach (rdf_get_namespaces() as $prefix => $namespace) { danielebarchiesi@4: $table_namespaces['rows'][] = array($prefix, $namespace); danielebarchiesi@4: } danielebarchiesi@4: // Only show label if there were conflicting namespaces. danielebarchiesi@4: if ($conflicting_namespaces) { danielebarchiesi@4: $output .= ' '; danielebarchiesi@4: } danielebarchiesi@4: $output .= theme('table', $table_namespaces); danielebarchiesi@4: danielebarchiesi@4: // Form to add namespaces. danielebarchiesi@4: $form = drupal_get_form('rdfx_admin_namespaces_form'); danielebarchiesi@4: $output .= drupal_render($form); danielebarchiesi@4: danielebarchiesi@4: return $output; danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: function rdfx_admin_namespaces_form($form, &$form_state) { danielebarchiesi@4: $form['prefix'] = array( danielebarchiesi@4: '#type' => 'textfield', danielebarchiesi@4: '#title' => t('Prefix'), danielebarchiesi@4: '#required' => TRUE, danielebarchiesi@4: '#description' => t('Choose a prefix for this namespace, e.g. dc, foaf, sioc. This prefix will be used as an abbreviation for the namespace URI.'), danielebarchiesi@4: ); danielebarchiesi@4: $form['ns_uri'] = array( danielebarchiesi@4: '#type' => 'textfield', danielebarchiesi@4: '#title' => t('Namespace URI'), danielebarchiesi@4: '#required' => TRUE, danielebarchiesi@4: '#default_value' => isset($form_state['values']['ns_uri']) ? $form_state['values']['ns_uri'] : NULL, danielebarchiesi@4: '#description' => t("Enter the URI of the namespace. Make sure it ends with either / or #."), danielebarchiesi@4: ); danielebarchiesi@4: $form['submit'] = array( danielebarchiesi@4: '#type' => 'submit', danielebarchiesi@4: '#value' => t('Save'), danielebarchiesi@4: ); danielebarchiesi@4: return $form; danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: function rdfx_admin_namespaces_form_validate($form, &$form_state) { danielebarchiesi@4: // Loads the XML Namespace regular expression patterns. danielebarchiesi@4: module_load_include('inc', 'rdfx'); danielebarchiesi@4: danielebarchiesi@4: $prefix = $form_state['values']['prefix']; danielebarchiesi@4: $ns_uri = $form_state['values']['ns_uri']; danielebarchiesi@4: danielebarchiesi@4: // Ensures that the namespace is a valid URI. danielebarchiesi@4: if (!valid_url($ns_uri, $absolute = TRUE)) { danielebarchiesi@4: form_set_error('ns_uri', t('The namespace URI must be a valid URI.')); danielebarchiesi@4: } danielebarchiesi@4: // Ensures the namespace URI ends in either / or #. danielebarchiesi@4: if (!preg_match('/(\/|\#)$/', $ns_uri)) { danielebarchiesi@4: form_set_error('ns_uri', t('The namespace URI must end in either a / or a #.')); danielebarchiesi@4: } danielebarchiesi@4: // Ensures the prefix is well formed according to the specification. danielebarchiesi@4: if (!preg_match('/^' . PREFIX .'$/', $prefix)) { danielebarchiesi@4: form_set_error('prefix', t('The prefix must follow the !link.', array('!link' => 'XML Namespace Specification'))); danielebarchiesi@4: } danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: function rdfx_admin_namespaces_form_submit($form, &$form_state) { danielebarchiesi@4: $prefix = $form_state['values']['prefix']; danielebarchiesi@4: $ns_uri = $form_state['values']['ns_uri']; danielebarchiesi@4: // Prepares a fake empty vocabulary for _rdfx_save_vocabulary() to save the danielebarchiesi@4: // namespace and prefix. danielebarchiesi@4: // @todo use API when http://drupal.org/node/1117646 is fixed. danielebarchiesi@4: $vocabulary = array( danielebarchiesi@4: 'title' => array(), danielebarchiesi@4: 'description' => array(), danielebarchiesi@4: 'namespaces' => array(), danielebarchiesi@4: ); danielebarchiesi@4: _rdfx_save_vocabulary($ns_uri, $prefix, $vocabulary); danielebarchiesi@4: drupal_set_message(t('The namespace @namespace has been saved with the prefix @prefix.', array('@namespace' => $ns_uri, '@prefix' => $prefix))); danielebarchiesi@4: }