Browse Source

Added url alias support to tripal entities :-)

Lacey Sanderson 9 years ago
parent
commit
d3c021ce00

+ 56 - 3
tripal_entities/includes/TripalBundleUIController.inc

@@ -154,13 +154,14 @@ function tripal_entities_tripal_bundle_form($form, &$form_state, $entityDataType
 
   $form['set_titles']['explanation'] = array(
     '#type' => 'item',
-    '#markup' => t('<p>The format below is used to determine the title displayed on content
+    '#markup' => t('<p>The format below is used to determine the title displayed on %type content
       pages. This ensures all content of this type is consistent while still allowing you
       to indicate which data you want represented in the title (ie: which data would most
       identify your content).</p>
       <p>Keep in mind that it might be confusing to users if more than
       one page has the same title. We recommend you <strong>choose a combination of tokens that
-      will uniquely identify your content</strong>.</p>'),
+      will uniquely identify your content</strong>.</p>',
+      array('%type' => $entity_type->label)),
   );
 
   $form['set_titles']['title_format'] = array(
@@ -188,9 +189,56 @@ function tripal_entities_tripal_bundle_form($form, &$form_state, $entityDataType
     '#value' => serialize($tokens)
   );
 
+  $token_markup = theme_token_list($tokens);
   $form['set_titles']['token_display']['content'] = array(
     '#type' => 'item',
-    '#markup' => theme_token_list($tokens)
+    '#markup' => $token_markup
+  );
+
+  // Set URL Alias Pattern.
+  //-------------------------
+  // @TODO: Find a way to use the Entity ID in the url.
+  $url_pattern = tripal_get_bundle_variable('url_format', $entity_type->id, '');
+  
+  $form['url'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('URL Path options'),
+    '#collapsible' => TRUE,
+    '#collapsed' => FALSE,
+    '#tree' => TRUE,
+    '#group' => 'additional_settings',
+  );
+  
+  $form['url']['explanation'] = array(
+    '#type' => 'item',
+    '#markup' => t('<p>The pattern below is used to specify the URL of %type content pages. 
+    This allows you to present more friendly, informative URLs to your user.</p>
+    <p><strong>You must choose a combination of tokens that results in a unique path for 
+    each page!</strong></p>',
+    array('%type' => $entity_type->label)),
+  );
+
+  $form['url']['url_pattern'] = array(
+    '#type' => 'textarea',
+    '#title' => t('URL Alias Pattern'),
+    '#description' => t('You may rearrange elements in this text box to customize the url 
+      alias. The available tokens are listed below. <strong>Make sure the pattern forms a 
+      valid, unique URL</strong>. Leave this field blank to use the original path.'),
+    '#default_value' => $url_pattern,
+    '#rows' => 1
+  );
+
+  $form['url']['token_display'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Available Tokens'),
+    '#description' => t('Copy the token and paste it into the "URL Alias Pattern" text field above.'),
+    '#collapsible' => TRUE,
+    '#collapsed' => TRUE
+  );
+
+  $form['url']['token_display']['content'] = array(
+    '#type' => 'item',
+    '#markup' => $token_markup
   );
 
   // Submit Buttons
@@ -258,6 +306,11 @@ function tripal_entities_tripal_bundle_form_submit($form, &$form_state) {
       $bundle_entity,
       $form_state['values']['set_titles']['title_format']
     );
+    
+    // Save the URL alias pattern if it's set.
+    if ($form_state['values']['url']['url_pattern']) {
+      tripal_set_bundle_variable('url_format', $bundle_entity->id, $form_state['values']['url']['url_pattern']);
+    }
 
     $form_state['redirect'] = 'admin/structure/bio-data';
     drupal_set_message(t('Successfully saved %type content type.', array('%type' => $form_state['build_info']['args'][0]->label)));

+ 122 - 2
tripal_entities/includes/TripalEntityController.inc

@@ -119,6 +119,124 @@ class TripalEntityController extends EntityAPIController {
     }
   }
 
+  /**
+   * Sets the URL alias for an entity.
+   */
+  public function setAlias($entity, $alias = NULL) {
+    $source_url = "bio-data/$entity->id";
+    
+    // If no alias was supplied then we should try to generate one using the
+    // default format set by admins.
+    if (!$alias) {
+    
+      // First get the format for the url alias based on the bundle of the entity.
+      $bundle_entity = tripal_bundle_load($entity->bundle);
+      $alias = tripal_get_bundle_variable('url_format', $bundle_entity->id);
+
+      // Determine which tokens were used in the format string
+      if (preg_match_all('/\[\w+\]/', $alias, $matches)) {
+        $used_tokens = $matches[0];
+
+        foreach($used_tokens as $token) {
+          $field = str_replace(array('.','[',']'),array('__','',''),$token);
+
+          $value = '';
+          if (isset($entity->{$field})) {
+
+            // Render the value from the field.
+            // @TODO: Handle the case where thefield is empty... currently returns error.
+            $field_value = field_get_items('TripalEntity', $entity, $field);
+            $field_render_arr = field_view_value('TripalEntity', $entity, $field, $field_value[0]);
+            $value = render($field_render_arr);
+          }
+          $alias = str_replace($token, trim($value), $alias);
+        }
+      }
+    }
+
+    // Make sure the alias doesn't contain spaces.
+    $alias = preg_replace('/\s+/','-',$alias);
+    // Or any non alpha numeric characters.
+    $alias = preg_replace('/[^a-zA-Z0-9\-\/]/','',$alias);
+    $alias = preg_replace('/_/','-',$alias);
+    
+    if ($alias) {
+        
+      // Determine if this alias has already been used.
+      $num_aliases = db_query('SELECT count(*) as num_alias FROM {url_alias} WHERE alias=:alias',
+        array(':alias' => $alias))->fetchField();
+      
+      // Either there isn't an alias yet so we just create one.
+      // OR an Alias already exists but we would like to add a new one.
+      if ($num_aliases == 0) {
+      
+        // First delete any previous alias' for this entity.
+        path_delete(array('source' => $source_url));
+        
+        // Then save the new one.
+        $path = array('source' => $source_url, 'alias' => $alias);
+        path_save($path);
+      }
+      // If there is only one alias matching then it might just be that we already
+      // assigned this alias to this entity in a previous save.
+      elseif ($num_aliases == 1) {
+      
+        // Checking to see if the single alias is for the same entity and if not
+        // warning the admin that the alias is already used (ie: not unique?)
+        $same_alias = db_query('SELECT count(*) as num_alias FROM {url_alias} WHERE alias=:alias AND source=:source',
+          array(':alias' => $alias, ':source' => $source_url))->fetchField();
+        if (!$same_alias) {
+
+          $msg = 'The URL alias, %alias, already exists for another page. Please ensure the pattern 
+            supplied on the <a href="!link" target="_blank">%type Edit Page</a> under URL Path options is unique.';
+          $msg_var = array(
+              '%alias' => $alias, 
+              '!link' => url("admin/structure/bio-data/manage/$entity->bundle"),
+              '%type' => $entity->bundle
+            );
+          tripal_report_error(
+            'trpentity',
+            TRIPAL_WARNING,
+            $msg,
+            $msg_var
+          );
+          drupal_set_message(t($msg, $msg_var), 'warning');
+          
+        }
+      }
+      // If there are more then one alias' matching what we generated then there's 
+      // a real problem and we need to warn the administrator.
+      else {
+        $aliases = db_query('SELECT source FROM {url_alias} WHERE alias=:alias',
+          array(':alias' => $alias))->fetchAll();
+        $pages = array();
+        foreach($aliases as $a) {
+          $pages[] = $a->source;
+        }
+
+        $msg = 'The URL alias, %alias, already exists for multiple pages! Please ensure the pattern 
+          supplied on the <a href="!link" target="_blank">%type Edit Page</a> under URL Path options is unique.';
+        $msg_var = array(
+            '%alias' => $alias, 
+            '!link' => url("admin/structure/bio-data/manage/$entity->bundle"),
+            '%type' => $entity->bundle
+          );
+        drupal_set_message(t($msg, $msg_var), 'error');
+        
+        $msg .= ' This url alias has already been used for the following pages: %pages. 
+          You can manually delete alias\' using a combination of path_load() and path_delete().';
+        $msg_var['%pages'] = implode(', ', $pages);
+        tripal_report_error(
+          'trpentity',
+          TRIPAL_ERROR,
+          $msg,
+          $msg_var
+        );
+          
+      }
+    }
+  }
+  
   /**
    * Saves the custom fields using drupal_write_record().
    */
@@ -172,8 +290,10 @@ class TripalEntityController extends EntityAPIController {
       }
       
       // Set the title for this entity.
-      $ec = new TripalEntityController($entity->type);
-      $ec->setTitle($entity);
+      $this->setTitle($entity);
+      
+      // Set the path/url alias for this entity.
+      $this->setAlias($entity);
 
       // Invoke either hook_entity_update() or hook_entity_insert().
       module_invoke_all('entity_postsave', $entity, $entity->type);