You are here

pcp.module in Profile Complete Percent 6.2

Same filename and directory in other branches
  1. 8 pcp.module
  2. 5 pcp.module
  3. 6 pcp.module
  4. 7 pcp.module

Allows users with valid permissions to tag profile fields created from the profile module as required fields for a users profile to be considered complete.

File

pcp.module
View source
<?php

/**
 * @file
 * Allows users with valid permissions to tag profile fields created
 * from the profile module as required fields for a
 * users profile to be considered complete.
 */

/**
 * Implementation of hook_perm()
 */
function pcp_perm() {
  return array(
    'administer pcp',
  );
}

/**
 * Implementation of hook_menu()
 */
function pcp_menu() {
  $items = array();
  $items['admin/user/pcp'] = array(
    'title' => 'Profile Complete Percentages',
    'description' => 'Tag profile fields as required for percent complete handling.',
    'page callback' => 'pcp_admin_settings',
    'access arguments' => array(
      'administer pcp',
    ),
  );
  return $items;
}

/**
 * Implementation of hook_block()
 */
function pcp_block($op = 'list', $delta = 0, $edit = array()) {
  switch ($op) {
    case 'list':
      $blocks = array();
      $blocks[0]['info'] = t('Profile Complete Percentage');
      return $blocks;
      break;
    case 'view':
      $block = array();
      switch ($delta) {
        case 0:
          if (user_is_logged_in()) {
            global $user;
            $complete_data = pcp_get_complete_percentage_data($user);
            $doHide = variable_get('pcp_hide_block_on_complete', 0);
            if ($doHide && $complete_data['nextfield'] == '') {
              $subject = '';
              $content = '';
            }
            else {
              $subject = t('Profile Complete');
              $content = theme('pcp_profile_percent_complete', $complete_data);
            }
            $block['subject'] = $subject;
            $block['content'] = $content;
          }
          break;
      }
      return $block;
      break;
  }
}

/**
 * Implementation of hook_form_FORM_ID_alter().
 */
function pcp_form_user_admin_settings_alter(&$form, $form_state) {
  if (user_access('administer pcp')) {
    $form['pictures']['settings']['pcp_enable_user_picture'] = array(
      '#title' => 'Make required for PCP module',
      '#type' => 'checkbox',
      '#default_value' => variable_get('pcp_enable_user_picture', 0),
      '#description' => t('Checking this box will tag this field as a required field for completion of the users profile.'),
    );
    $form['#submit'][] = 'pcp_user_admin_settings_submit';
  }
}

/**
 * Implementation of hook_form_FORM_ID_alter().
 */
function pcp_form_profile_field_form_alter(&$form, $form_state) {
  if (user_access('administer pcp')) {
    $form['fields']['pcp_tag'] = array(
      '#type' => 'checkbox',
      '#title' => t('Make required for PCP module'),
      '#description' => t('Checking this box will tag this field as a required field for completion of the users profile.'),
      '#default_value' => _pcp_field_is_tagged($form['fid']['#value']),
    );
    $form['#submit'][] = 'pcp_profile_field_form_submit';
  }
}

/**
 * Implementation of hook_form_FORM_ID_alter().
 */
function pcp_form_user_profile_form_alter(&$form, $form_state) {
  if (isset($_GET['fieldname']) && $_GET['fieldname'] != '') {
    $fieldname = 'edit-' . preg_replace("/_/", "-", $_GET['fieldname']);
    drupal_add_js("\n      \$('#" . $fieldname . "').css({\n        'border' : '2px solid red'\n        });\n    ", 'inline', 'footer');
  }
}

/**
 * Implementation of hook_form_FORM_ID_alter().
 */
function pcp_form_profile_field_delete_alter(&$form, $form_state) {
  $form['#submit'][] = 'pcp_delete_field_requireness';
}

/**
 * Called when a user submits a profile field form from the
 * profile module (when adding or editing a profile field).
 */
function pcp_profile_field_form_submit($form, &$form_state) {
  $fid = $form_state['values']['fid'] ? $form_state['values']['fid'] : db_result(db_query("SELECT MAX(fid) FROM {profile_fields}"));
  db_query("DELETE FROM {profile_pcp} WHERE fid = %d", $form_state['values']['fid']);
  if ($form_state['values']['pcp_tag']) {
    db_query("INSERT INTO {profile_pcp} (`fid`) VALUES (%d)", $fid);
  }
}

/**
 * Called when a user deletes a profile field
 * We then need to delete the pcp value too
 */
function pcp_delete_field_requireness($form, &$form_state) {
  db_query("DELETE FROM {profile_pcp} WHERE fid = %d", $form_state['values']['fid']);
}

/**
 * Called when a user submits the admin user settings form.
 */
function pcp_user_admin_settings_submit($form, &$form_state) {
  variable_set('pcp_enable_user_picture', $form_state['values']['pcp_enable_user_picture']);
}

/**
 * Menu Callback Function
 *  Build output of the pcp module settings which allows the
 *  administrator to tag specific profile fields which will be
 *  used to determine the completion of a users profile.
 */
function pcp_admin_settings() {
  return drupal_get_form('pcp_admin_settings_form');
}

/**
 * Admin settings form
 */
function pcp_admin_settings_form() {
  $form = array();
  $form['general_settings'] = array(
    '#type' => 'fieldset',
    '#title' => 'General Settings',
  );
  $form['general_settings']['hide_block_on_complete'] = array(
    '#type' => 'checkbox',
    '#title' => 'Hide Block When Complete',
    '#default_value' => variable_get('pcp_hide_block_on_complete', 0),
    '#description' => t('When a user reaches 100% complete of their profile, do you want the profile complete percent block to go away? If so, check this box on.'),
  );
  $form['profile_field_settings'] = array(
    '#type' => 'fieldset',
    '#title' => 'Profile Fields',
    '#description' => t('Checking a profile field below will add that field to the logic of the complete percentage.'),
  );

  // Add user picture support
  if (variable_get('user_pictures', 0)) {
    $form['profile_field_settings']['pcp_enable_user_picture'] = array(
      '#title' => 'Enable User Picture Support',
      '#type' => 'checkbox',
      '#default_value' => variable_get('pcp_enable_user_picture', 0),
      '#description' => t('Picture support has been turned on, do you want to make it required as part of Profile Complete Percent? Checking this box will make it required.'),
    );
  }
  $options = pcp_admin_settings_form_data();
  if ($options['profile_fields_options']) {
    $form['profile_field_settings']['profile_fields'] = array(
      '#title' => t('Profile Fields'),
      '#type' => 'checkboxes',
      '#options' => $options['profile_fields_options'],
      '#default_value' => $options['default_values'],
    );
  }

  // Add user terms support
  if (module_exists('user_terms')) {
    $vocabs = taxonomy_get_vocabularies();
    $vocabs_enabled = variable_get('user_terms_vocabs', array());
    $all_vocabs = array();
    foreach ($vocabs_enabled as $vid) {
      $all_vocabs[$vid] = $vocabs[$vid]->name;
    }
    if (!empty($vocabs_enabled)) {
      $form['profile_field_settings']['pcp_enabled_user_terms_vocabs'] = array(
        '#title' => t('User Terms Vocabularies'),
        '#type' => 'checkboxes',
        '#options' => $all_vocabs,
        '#default_value' => variable_get('pcp_enabled_user_terms_vocabs', array()),
      );
    }
  }
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Save'),
  );
  return $form;
}

/**
 * Admin settings form submit
 */
function pcp_admin_settings_form_submit($form, &$form_state) {

  // Process the General Settings data
  variable_set('pcp_hide_block_on_complete', $form_state['values']['hide_block_on_complete']);
  variable_set('pcp_enable_user_picture', $form_state['values']['pcp_enable_user_picture']);
  variable_set('pcp_enabled_user_terms_vocabs', $form_state['values']['pcp_enabled_user_terms_vocabs']);

  // Process the profile fields that have been modified if available.
  if (is_array($form_state['values']['profile_fields']) && !empty($form_state['values']['profile_fields'])) {
    db_query("DELETE FROM {profile_pcp}");
    foreach ($form_state['values']['profile_fields'] as $fid) {
      if ($fid) {
        db_query("INSERT INTO {profile_pcp} VALUES (%d)", $fid);
      }
    }
    drupal_set_message("Your settings have been saved.");
  }
}

/**
 * Function that sets up parameters to be used
 * when the pcp_admin_settings_form() function
 * is executed.
 *
 * @return - assoc array
 *  ['profile_fields_options']
 *    - An associative array of all fields created from the profile module.
 *  ['default_values']
 *    - An indexed array of all (if any) default values for the form.
 */
function pcp_admin_settings_form_data() {
  $profile_fields_options = array();
  $default_values = array();
  $profile_fields = pcp_get_profile_fields();
  foreach ($profile_fields as $key => $value) {
    $field_options[$value['fid']] = $value['title'];
  }
  $tagged_profile_fields = pcp_get_tagged_profile_fields();
  foreach ($tagged_profile_fields as $key => $value) {
    $default_values[] = $value['fid'];
  }
  $options = array();
  $options['profile_fields_options'] = $field_options;
  $options['default_values'] = $default_values;
  return $options;
}

/**
 * Return a users profile field values that have been saved
 * for a given user.
 *
 * @param int $uid - The uid of the user we are returning data for.
 *
 * @return assoc array of all profile fields for the user.
 */
function pcp_get_user_profile_values($uid) {
  $values = array();
  if ($uid) {
    $query = db_query("SELECT * FROM {profile_values} WHERE uid = %d", $uid);
    while ($result = db_fetch_array($query)) {
      $values[$result['fid']] = $result['value'];
    }
  }
  return $values;
}

/**
 * Return a users additional field values that have been saved
 * for a given user.
 *
 * @param int $uid - The uid of the user we are returning data for.
 *
 * @return assoc array of all profile fields for the user.
 */
function pcp_get_user_additional_values($uid) {
  $values = array();
  if ($uid) {
    $account = user_load($uid);
    $values['user_picture'] = $account->picture;
    if (module_exists('user_terms')) {
      $user_terms_vocabs = variable_get('pcp_enabled_user_terms_vocabs', array());
      foreach ($account->user_terms as $term) {
        $vid = $term['vid'];
        $values['user_terms_' . $vid][] = $term;
      }
    }
  }
  return $values;
}

/**
* Get the profile complete percentage data for a given user.
*
* @param obj $user
*  - The user object to get data for.
*
* @return assoc array of all values needed at the theme layer.
*  - Refer to comments in theme_pcp_profile_percent_complete() for specific values.
*/
function pcp_get_complete_percentage_data($user) {
  $profile_fields = pcp_get_tagged_profile_fields();
  $additional_fields = pcp_get_additional_tagged_fields();
  $fields = $profile_fields + $additional_fields;
  $user_profile_values = pcp_get_user_profile_values($user->uid);
  $user_additional_values = pcp_get_user_additional_values($user->uid);
  $user_values = $user_profile_values + $user_additional_values;
  $percent = 0;
  $complete = 0;
  $nextfield_set = FALSE;
  if (is_array($fields) && !empty($fields)) {

    //Shuffle the fields to display a random field to fill in (issue #708382)
    shuffle($fields);
    foreach ($fields as $key => $value) {
      if (isset($user_values[$value['fid']]) && ($user_values[$value['fid']] == '' || $user_values[$value['fid']] == '0' && $value['type'] == 'selection')) {
        if ($nextfield_set === FALSE) {
          $nextfield_set = TRUE;
          $fid = $value['fid'];
          $nextfield_fid = $fid;
          if (is_numeric($fid)) {
            $nextdata = db_fetch_array(db_query("SELECT title, name, category FROM {profile_fields} WHERE fid = %d", $fid));
            $nextfield = $nextdata['title'];
            $nextcategory = $nextdata['category'];
            $nextname = $nextdata['name'];
          }
          elseif ($fid == 'user_picture') {
            $nextfield = $value['title'];
            $nextcategory = 'Default';
            $nextname = $value['name'];
          }
          elseif (substr($fid, 0, 10) == 'user_terms' && variable_get('pcp_enabled_user_terms_vocabs', array())) {
            $nextfield = $value['title'];
            $nextcategory = $value['category'] == 'account' ? 'Default' : $value['category'];
            $nextname = $value['name'];
          }
        }
        continue;
      }
      $complete++;
    }
    $dec = number_format($complete / count($fields), 2);
    $percent = $dec * 100;
    if ($nextfield_set) {
      $next = number_format(($complete + 1) / count($fields), 2);
      $nextpercent = $next * 100;
    }
  }
  $complete_data = array();
  $complete_data['uid'] = $user->uid;
  $complete_data['percent'] = $percent;
  $complete_data['completed'] = $complete;
  $complete_data['incomplete'] = count($fields) - $complete;
  $complete_data['total'] = count($fields);
  $complete_data['nextfield'] = $nextfield;
  $complete_data['nextfield_fid'] = $nextfield_fid;
  $complete_data['nextpercent'] = $nextpercent;
  $complete_data['nextcategory'] = $nextcategory;
  $complete_data['nextname'] = $nextname;
  return $complete_data;
}

/**
 * Get all the profile fields that have been tagged.
 * If an $fid is passed in, only the data for that field will be returned.
 *
 * @param int $fid - The fid of the field data should be returned for. If 0, all fields are returned.
 *
 * @return indexed array - All fields and their information returned from the query.
 */
function pcp_get_tagged_profile_fields($fid = 0) {
  $profile_role_used = module_exists('profile_role');
  if ($fid > 0) {
    $query = db_query("SELECT * FROM {profile_pcp} LEFT JOIN {profile_fields} USING(fid) WHERE fid = %d", $fid);
  }
  else {
    $query = db_query("SELECT * FROM {profile_pcp} LEFT JOIN {profile_fields} USING(fid)");
  }
  $fields = array();
  while ($result = db_fetch_array($query)) {
    if ($profile_role_used) {
      global $user;
      if (profile_role_access_category($user, $result['category'])) {
        $fields[] = $result;
      }
    }
    else {
      $fields[] = $result;
    }
  }
  return $fields;
}

/**
 * Get all the profile fields stored in the system, tagged or not tagged.
 */
function pcp_get_profile_fields() {
  $query = db_query("SELECT * FROM {profile_fields}");
  $fields = array();
  while ($result = db_fetch_array($query)) {
    $fields[] = $result;
  }
  return $fields;
}

/**
 * Get all additional tagged fields that where not created
 * using the profile module. This allows additional PCP
 * support for other drupal features.
 */
function pcp_get_additional_tagged_fields() {
  $fields = array();

  // Enable user picture support.
  if (variable_get('pcp_enable_user_picture', 0) && variable_get('user_pictures', 0)) {
    $fields['user_picture'] = array(
      'fid' => 'user_picture',
      'title' => 'User Picture',
      'name' => 'picture_upload',
    );
  }
  if (module_exists('user_terms')) {
    $vocabs = taxonomy_get_vocabularies();
    $user_terms_vocabs = variable_get('pcp_enabled_user_terms_vocabs', array());
    $vocabs_path = variable_get('user_terms_vocabs_path', array());
    $all_vocabs = array();
    foreach ($user_terms_vocabs as $vid) {
      $all_vocabs[$vid] = $vocabs[$vid]->name;
    }
    foreach ($all_vocabs as $vid => $name) {
      $fields['user_terms_' . $vid] = array(
        'fid' => 'user_terms_' . $vid,
        'title' => $name,
        'name' => 'user_terms_' . $vid,
        'category' => $vocabs_path[$vid],
      );
    }
  }
  return $fields;
}
function pcp_theme() {
  return array(
    'pcp_profile_percent_complete' => array(
      'arguments' => array(
        'complete_data' => NULL,
      ),
    ),
  );
}

/**
 * Block Theme function that displays the default output of a users
 * profile complete percent. Use this theme function to override
 * the output / display of this block.
 *
 * @param - assoc array $complete_data
 *  ['uid'] - int - The user ID of the user viewing the page.
 *  ['percent'] - int - A number that represents the total percent complete (ie 50).
 *  ['completed'] - int - How many fields total that have been completed (filled out) by $user.
 *  ['incomplete'] - int - How many fields still need to be filled out.
 *  ['total'] - int - The count of all tagged profile fields.
 *  ['nextfield'] - str - The next field to fill out that is currently empty.
 *  ['nextfield_fid'] - int or str - The fid identifier of the field being passed in.
 *  ['nextpercent'] - int - What the users total percent complete value will be when ['nextfield'] is complete.
 *  ['nextcategory] - str - The category the next field falls under for targeting with a link.
 *  ['nextname'] - str - The field name of the next field for field focus after linked to the profile field.
 */
function theme_pcp_profile_percent_complete($complete_data) {
  $output = '<style type="text/css">';
  $output .= '#pcp-percent-bar-wrapper {width: 100%; border: 1px solid #000; padding: 1px;}';
  $output .= '#pcp-percent-bar { width: ' . $complete_data['percent'] . '%; height: 10px; background-color: #777777;}';
  $output .= '</style>';
  $output .= '<div id="pcp-wrapper">';
  $output .= t('!complete% Complete', array(
    '!complete' => $complete_data['percent'],
  ));
  $output .= '<div id="pcp-percent-bar-wrapper">';
  $output .= '<div id="pcp-percent-bar"></div>';
  $output .= '</div>';
  $output .= '</div>';
  if ($complete_data['nextfield'] && $complete_data['nextpercent']) {
    if ($complete_data['nextcategory'] == 'Default') {
      $nextpath = 'user/' . $complete_data['uid'] . '/edit';
    }
    else {
      $nextpath = 'user/' . $complete_data['uid'] . '/edit/' . $complete_data['nextcategory'];
    }
    $element_id = 'edit-' . str_replace('_', '-', $complete_data['nextname']);
    $output .= t('Filling out <em>!empty-field</em> will bring your profile to !complete% Complete', array(
      '!empty-field' => l($complete_data['nextfield'], $nextpath, array(
        'query' => 'fieldname=' . $complete_data['nextname'],
        'fragment' => $element_id,
      )),
      '!complete' => $complete_data['nextpercent'],
    ));
  }
  return $output;
}

/**
 * Implementation of hook_rules_condition_info().
 *
 * @ingroup rules
 * @see content_complete_completeness_percentage_form
 */
function pcp_rules_condition_info() {
  return array(
    'pcp_condition_check_profile_fields_completeness' => array(
      'label' => t('Check profile fields completeness'),
      'arguments' => array(
        'user' => array(
          'type' => 'user',
          'label' => t('User'),
        ),
      ),
      'help' => 'Evaluates to TRUE, if all the the selected user profile fields are filled in.',
      'module' => 'Profile Complete Percent',
    ),
  );
}

/**
 * Rules Condition form configuration - select the profile fields to check
 *
 * @see pcp_rules_condition_info
 */
function pcp_condition_check_profile_fields_completeness_form($settings = array(), &$form) {
  $options = pcp_admin_settings_form_data();
  $form['settings']['profile_fields'] = array(
    '#title' => t('Profile Fields'),
    '#type' => 'checkboxes',
    '#options' => $options['profile_fields_options'],
    '#default_value' => isset($settings['profile_fields']) ? $settings['profile_fields'] : array(),
    '#description' => t('Check which fields the user has to fill in'),
  );
}

/**
 * Rules Condition - Are the selected user profile fields filed in?
 *
 * @param $user
 *   The user for which the condition is checked.
 * @param $settings
 *   The configured settings of the rule condition
 *
 * @see pcp_condition_check_profile_fields_completeness_form
 * @see pcp_rules_condition_info
 *
 * @return TRUE or FALSE
 */
function pcp_condition_check_profile_fields_completeness($user, $settings) {
  $edit_categories = array();
  profile_load_profile($user);
  if ($settings['profile_fields']) {
    $result = db_query("SELECT fid, title, name, category FROM {profile_fields} WHERE fid IN (%d)", implode(', ', $settings['profile_fields']));
    while ($field = db_fetch_object($result)) {
      if (!$user->{$field->name}) {
        return FALSE;
      }
    }
  }
  return TRUE;
}

/**
 * Implementation of hook_rules_action_info
 */
function pcp_rules_action_info() {
  return array(
    'pcp_action_redirect_user_to_editform' => array(
      'label' => t('Redirect the user to his own profile edit page'),
      'arguments' => array(
        'user' => array(
          'type' => 'user',
          'label' => t('User whos profile fields should be filled in'),
        ),
      ),
      'module' => 'Profile Complete Percent',
    ),
  );
}

/**
 * Rules Action - Redirect the user to his profile edit page
 *
 * @param $user
 *   The user for which the action is performed.
 * @param $settings
 *   The configured settings of the rule action
 *
 * @see pcp_rules_action_info
 *
 * @return Perform the redirection
 */
function pcp_action_redirect_user_to_editform($user, $settings) {
  $settings = pcp_get_condition_settings('pcp_condition_check_profile_fields_completeness');
  $edit_categories = array();
  profile_load_profile($user);
  if ($settings['profile_fields']) {
    $result = db_query("SELECT fid, title, name, category FROM {profile_fields} WHERE fid IN (%d)", implode(', ', $settings['profile_fields']));
    while ($field = db_fetch_object($result)) {
      if (!$user->{$field->name}) {
        drupal_set_message(t('Please fill in "<i>' . $field->category . '</i>".'), 'warning');

        // Necessary to avoid redirect loop or malfunctioning
        unset($_REQUEST['destination']);
        unset($_REQUEST['edit']['destination']);
        drupal_goto('user/' . $user->uid . '/edit/' . $field->category);
      }
    }
  }
}

/**
 * Check if a profile field is tagged as to be filled in.
 * Returns TRUE or FALSE
 */
function _pcp_field_is_tagged($fid) {
  $tag = TRUE;
  $field_data = pcp_get_tagged_profile_fields($fid);
  if (!$field_data[0]['fid']) {
    $tag = FALSE;
  }
  return $tag;
}

/**
 * Check if a profile category is tagged as to be filled in.
 * Returns TRUE or FALSE
 */
function _pcp_category_status($category = '') {
  return 'all';
}

/**
 * Helper function to get the setting of a particular condition
 *
 * @param Condition name $name
 * @return Array settings
 */
function pcp_get_condition_settings($name) {
  $rules = rules_get_configured_items('rules');
  foreach ($rules as $rule) {
    if ($rule['#conditions']) {
      foreach ($rule['#conditions'] as $condition) {
        if ($condition['#name'] == $name) {
          return $condition['#settings'];
        }
      }
    }
  }
}

Functions

Namesort descending Description
pcp_action_redirect_user_to_editform Rules Action - Redirect the user to his profile edit page
pcp_admin_settings Menu Callback Function Build output of the pcp module settings which allows the administrator to tag specific profile fields which will be used to determine the completion of a users profile.
pcp_admin_settings_form Admin settings form
pcp_admin_settings_form_data Function that sets up parameters to be used when the pcp_admin_settings_form() function is executed.
pcp_admin_settings_form_submit Admin settings form submit
pcp_block Implementation of hook_block()
pcp_condition_check_profile_fields_completeness Rules Condition - Are the selected user profile fields filed in?
pcp_condition_check_profile_fields_completeness_form Rules Condition form configuration - select the profile fields to check
pcp_delete_field_requireness Called when a user deletes a profile field We then need to delete the pcp value too
pcp_form_profile_field_delete_alter Implementation of hook_form_FORM_ID_alter().
pcp_form_profile_field_form_alter Implementation of hook_form_FORM_ID_alter().
pcp_form_user_admin_settings_alter Implementation of hook_form_FORM_ID_alter().
pcp_form_user_profile_form_alter Implementation of hook_form_FORM_ID_alter().
pcp_get_additional_tagged_fields Get all additional tagged fields that where not created using the profile module. This allows additional PCP support for other drupal features.
pcp_get_complete_percentage_data Get the profile complete percentage data for a given user.
pcp_get_condition_settings Helper function to get the setting of a particular condition
pcp_get_profile_fields Get all the profile fields stored in the system, tagged or not tagged.
pcp_get_tagged_profile_fields Get all the profile fields that have been tagged. If an $fid is passed in, only the data for that field will be returned.
pcp_get_user_additional_values Return a users additional field values that have been saved for a given user.
pcp_get_user_profile_values Return a users profile field values that have been saved for a given user.
pcp_menu Implementation of hook_menu()
pcp_perm Implementation of hook_perm()
pcp_profile_field_form_submit Called when a user submits a profile field form from the profile module (when adding or editing a profile field).
pcp_rules_action_info Implementation of hook_rules_action_info
pcp_rules_condition_info Implementation of hook_rules_condition_info().
pcp_theme
pcp_user_admin_settings_submit Called when a user submits the admin user settings form.
theme_pcp_profile_percent_complete Block Theme function that displays the default output of a users profile complete percent. Use this theme function to override the output / display of this block.
_pcp_category_status Check if a profile category is tagged as to be filled in. Returns TRUE or FALSE
_pcp_field_is_tagged Check if a profile field is tagged as to be filled in. Returns TRUE or FALSE