Thursday 30 April 2015

Blog about Improving the Drupal CMS User Experience.

I'm currently working for this Drupal Development Company in Newquay, Cornwall  . At which we've got round to adding Blogs.  Where I will be blogging regularly.

Check my latest blog

Improving the Drupal CMS User Experience


Basically it's my notes from Drupal Camp London on the Seminar of the same name. 

Tuesday 21 April 2015

Drupal 7 Taxonomy Ordering

What I need to do was Order my taxonomy from Parent to Child .

There are a couple of solutions to this; but I had issue with both .  Lets have a look at those first before I give my programmatical solution.

Hierarchal Term Formatter : https://www.drupal.org/project/hierarchical_term_formatter

Unfortunately installing this on my existing Drupal site causes all the fields in any views that contain taxonomy to disappear :/ Shame as this would have been perfect.

2. to order them BY ID, or NAME, or WEIGHT.
You need to create in Advance (Views) a Relationship pointing to that Taxonomy Vocabulary
Then you can add a Sort Filter



However this was the code that sorted the issue for me.

/**
 * @file Orders Taxonomy

 *

 * @param $tid - expecting a tid  

 * @param $no_results - the number of results that you'd like to return

 * @param $order - which tid first - child or most senior parent ?

 *

 * @return returns a string .

 */



function rcn_taxonomy_order($tid, $no_results = 1, $order = 'first') {



  $wrapper = entity_metadata_wrapper('taxonomy_term', $tid);

  $all_parents = $wrapper->parents_all->value();



  ($order == 'last') ? $all_parents = array_reverse($all_parents) : $all_parents;



  $stitch_term_array = '';

  foreach ($all_parents as $key => $term) {

    ($key < $no_results) ? $stitch_term_array .= $term->name . ", " : '';

  }



  return rtrim($stitch_term_array, ', ');



}

Tuesday 14 April 2015

Drupal 7 - Error Reported in log - array_splice() expects parameter in template.php


In Report Logs we we’re getting these errors on Clearing the Cache.  

Warning: array_splice() expects parameter 1 to be array, null given in omega_theme_registry_alter() (line 458 of */sites/all/themes/contrib/omega/omega/template.php).

Warning: array_search() expects parameter 2 to be array, null given in omega_theme_registry_alter() (line 445 of /Users/DJ/Sites/mampsites/sccbb/sites/all/themes/contrib/omega/omega/template.php).

Warning: array_unshift() expects parameter 1 to be array, null given in omega_theme_registry_alter() (line 447 of /Users/DJ/Sites/mampsites/sccbb/sites/all/themes/contrib/omega/omega/template.php).

Warning: array_splice() expects parameter 1 to be array, null given in omega_theme_registry_alter() (line 449 of /Users/DJ/Sites/mampsites/sccbb/sites/all/themes/contrib/omega/omega/template.php).

Notice: Undefined index: preprocess functions in omega_theme_registry_alter() (line 445 of /Users/DJ/Sites/mampsites/sccbb/sites/all/themes/contrib/omega/omega/template.php).


To test this I locally ran this test in the omega/template.php at line 445

// @todo temporary debugging code to look for an error
// check to see if this is an arry
if (!is_array($registry[$hook]['preprocess functions'])){
  watchdog('!array preprocess func', $hook);
}
if (!isset($registry[$hook]['preprocess functions'])){
  watchdog('!isset preprocess func', $hook);
}
// @todo end debugging



This report any hook preprocess functions that are not as should be .   Which returned the one result .  

‘block_swiper’



On checking we have a Swiper module installed. When disabled we no longer receive a PHP error message.   Also note on checking Clear Cache needs to be run each time. 

Thursday 2 April 2015

Drupal 7 - Adding a Delete Button to open in Modal PopUp

The task here was to add to existing code ; where we where adding a delete button like those being called in an already existing module.

The task check list. 
1. Find a delete Quiz result function in the Quiz module.   If there isn’t one this will need to be created. 

2. Create menu callback for modal form. 

3. Set in hook_menu

4. Write an access rule for this . 

5. Call up in View. 




1.  There was no Delete form so lets create one in modules/custom/rcni_saqs/includes/form.inc 

[code]

/**
 * @file
 * Custom forms.
 */

/**
 * Form builder.
 *
 * @param array $form
 *   An associative array containing the structure of the form.
 * @param array $form_state
 *   An array which stores information about the form.
 *
 * @return array
 *   Completed form array.
*/
function rcni_custom_delete_form($form, &$form_state, $quiz, $quiz_result_id) {
  $quiz_result = quiz_result_load($quiz_result_id);

  if (!$quiz_result) {
    return array('error' => array('#markup' => 'Could not find quiz result.'));
  }

  $form['quiz_result'] = array(
    '#type' => 'value',
    '#value' => $quiz_result,
  );

  try {
    $w_quiz = entity_metadata_wrapper('node', $quiz);
    $quiz_title = $w_quiz->label();
  }
  catch (EntityMetadataWrapperException $e) {
    watchdog_exception(‘my_custom', $e);
    $quiz_title = '';
  }

  $message = t("Are you sure that you want to delete your answers for %quiz_title?",
    array("%quiz_title" => $quiz_title));

  try {
    $w_quiz_result = entity_metadata_wrapper('quiz_result', $quiz_result);
    $redirect = "portfolio/portfolio/{$w_quiz_result->field_custom_field->raw()}";
  }
  catch (EntityMetadataWrapperException $e) {
    watchdog_exception(‘my_custom', $e);
    $redirect = 'eportfolio';
  }

  $form['submit_redirect'] = array(
    '#type' => 'value',
    '#value' => $redirect,
  );

  $caption = t("This action cannot be undone.");

  return confirm_form($form, $message, $redirect, $caption, t('Delete'));
}

/**
 * Form submit handler.
 *
 * @param array $form
 *   An associative array containing the structure of the form.
 * @param array $form_state
 *   An array which stores information about the form.
 */
function my_custom_delete_form_submit($form, &$form_state) {
  quiz_delete_results(array($form_state['values']['quiz_result']->result_id));
  $form_state['redirect'] = $form_state['values']['submit_redirect'];
}

[/code]


2.  Lets add that callback now to /cutom/rcni_modal/includes/saqs.inc

/**
 * @file
 * Modal form wrappers for SAQs.
 */

/**
 * CTools modal form wrapper function.
 *
 * @param object $quiz
 *   The quiz node the results belong to.
 * @param int $quiz_result_id
 *   The rid of the quiz result we're deleting.
 * @param bool $js
 *   Whether javascript is enabled.
 * @param bool $refresh
 *   Whether to refresh the base page on form submission.
 */
function my_modal_custom_delete_form_modal_callback($quiz, $quiz_result_id, $js = FALSE, $refresh = TRUE) {
  if (!$js) {
    if ($quiz_result = quiz_result_load($quiz_result_id)) {
      $portfolio_id = rcni_modal_get_parent_portfolio_id($quiz_result);
      $options = $portfolio_id ? array('query' => array('destination' => "portfolio/portfolio/{$portfolio_id}")) : array();
      drupal_goto("node/{$quiz->nid}/quiz-results/{$quiz_result_id}/delete", $options);
    }
    else {
      drupal_goto("eportfolio");
    }
  }
  else {
    $form_state = array(
      'ajax' => TRUE,
      'build_info' => array(
        'args' => array(
          $quiz->nid,
          $quiz_result_id,
        ),
      ),
      'rcni_modal' => TRUE,
    );

    $form_id = ‘my_custom_delete_form';
    form_load_include($form_state, 'inc', ‘my_custom', 'includes/form');
    my_modal_custom_form_modal_callback($form_id, $form_state, $refresh);
  }
}

3.  Build the menu item that it gets sent to. 


/**
 * Implements hook_menu().
 */
function my_modal_menu() {
  $items = array();

  $items['node/%quiz_menu/quiz-results/%quiz_rid/delete'] = array(
    'title' => 'Delete answers',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('rcni_saqs_delete_form', 1, 3),
    'access callback' => 'rcni_saqs_quiz_result_delete_access',
    'access arguments' => array(3),
    'file' => 'includes/form.inc',
  );

  return $items;
}


4.  The Access rule. 

/**
 * Access callback for deleting a quiz.
 *
 * @return bool
 *   True if user can delete quiz result.
 */
function rcni_saqs_quiz_result_delete_access($result_id) {
  if (user_access('delete any quiz results')) {
    return TRUE;
  }

  global $user;
  $quiz_result = quiz_result_load($result_id);

  if (!$quiz_result) {
    return FALSE;
  }

  return user_access('delete results for own quiz') && $user->uid == $quiz_result->uid;
}

5. 

[code]
.


[/code]