You are here

certificate.module in Certificate 7.3

Certificate module.

File

certificate.module
View source
<?php

/**
 * Certificate module.
 * @file
 */

/**
 * Certificate node form.
 */
function certificate_form($form, &$form_state, $certificate = NULL) {
  $form['title'] = array(
    '#type' => 'textfield',
    '#title' => t('Title'),
    '#default_value' => isset($certificate->title) ? $certificate->title : '',
    '#required' => TRUE,
    '#maxlength' => 128,
    '#size' => 60,
  );
  $form['name'] = array(
    '#type' => 'machine_name',
    '#title' => t('Machine name'),
    '#default_value' => isset($certificate->name) ? $certificate->name : '',
    '#required' => TRUE,
    '#maxlength' => 128,
    '#size' => 60,
    '#machine_name' => array(
      'source' => array(
        'title',
      ),
      'exists' => 'certificate_load_single',
    ),
  );
  $form['orientation'] = array(
    '#type' => 'radios',
    '#title' => t('Orientation'),
    '#default_value' => isset($certificate->orientation) ? $certificate->orientation : '',
    '#options' => array(
      'portrait' => t('Portrait'),
      'landscape' => t('Landscape'),
    ),
    '#required' => TRUE,
    '#description' => t('The orientation of the generated certificate.'),
  );
  $form['certificate_tokens'] = array(
    '#type' => 'fieldset',
    '#title' => t('Replacement tokens'),
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
  );
  $form['certificate_tokens']['tokens'] = array(
    '#markup' => theme('token_tree_link', array(
      'token_types' => array(
        'global',
        'node',
        'user',
        'certificate',
      ),
    )),
  );
  field_attach_form('certificate', $certificate, $form, $form_state);
  $form['actions']['#type'] = 'actions';
  $form['actions']['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Save'),
  );
  return $form;
}

/**
 * Certificate node form submit
 */
function certificate_form_submit(&$form, &$form_state) {
  $certificate = entity_ui_form_submit_build_entity($form, $form_state);
  if (entity_save('certificate', $certificate)) {
    drupal_set_message(t('The certificate %title has been saved.', array(
      '%title' => entity_label('certificate', $certificate),
    )));
  }
  else {
    drupal_set_message(t('There was an error saving the certificate'), 'error');
  }
  $form_state['redirect'] = 'admin/structure/certificates';
}

/**
 * Implements hook_menu().
 */
function certificate_menu() {
  $items = array();
  $items['admin/structure/certificates/mapping'] = array(
    'title' => 'Mapping',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'certificate_settings_form',
    ),
    'access arguments' => array(
      'administer certificates',
    ),
    'file' => 'certificate.admin.inc',
    'type' => MENU_LOCAL_TASK,
    'weight' => -4,
  );
  $items['admin/structure/certificates/mapping/groups'] = array(
    'title' => 'Field groups',
    'description' => 'Set up certificate field groups',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'certificate_field_grouping_form',
    ),
    'access arguments' => array(
      'administer certificates',
    ),
    'file' => 'certificate.admin.inc',
    'type' => MENU_LOCAL_TASK,
  );
  $items['admin/structure/certificates/mapping/list'] = array(
    'title' => 'Global',
    'type' => MENU_DEFAULT_LOCAL_TASK,
    'weight' => -5,
  );
  $items['admin/structure/certificates/mapping/groups/add'] = array(
    'title' => 'Add field group',
    'description' => 'Add a field group',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'certificate_field_grouping_add_form',
    ),
    'access arguments' => array(
      'administer certificates',
    ),
    'file' => 'certificate.admin.inc',
    'type' => MENU_LOCAL_ACTION,
  );

  /*
   $items['admin/structure/certificates/mapping/groups/delete/%'] = array(
   'title' => 'Delete field group',
   'description' => 'Delete a field group',
   'page callback' => 'drupal_get_form',
   'page arguments' => array('certificate_field_grouping_delete_form'),
   'page arguments' => array(6),
   'access arguments' => array('administer certificates'),
   'file' => 'certificate.admin.inc',
   'type' => MENU_LOCAL_TASK,
   );
  */
  $items['admin/structure/certificates/settings'] = array(
    'title' => 'Settings',
    'description' => 'Certificate settings.',
    'access arguments' => array(
      'administer certificates',
    ),
    'file' => 'certificate.admin.inc',
    'type' => MENU_LOCAL_TASK,
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'certificate_admin_settings_form',
    ),
  );
  $items['admin/structure/certificates/preview/%'] = array(
    'title' => 'Certificate preview',
    'description' => 'Display earned certificate for this node',
    'page callback' => 'certificate_preview',
    'page arguments' => array(
      4,
    ),
    'access arguments' => array(
      'administer certificates',
    ),
    'file' => 'certificate.pages.inc',
    'type' => MENU_CALLBACK,
  );

  // Certificate tab on nodes.
  $items['node/%node/certificate'] = array(
    'title' => 'Certificate',
    'description' => 'Display earned certificate for this node',
    'page callback' => 'certificate_node_certificate',
    'page arguments' => array(
      1,
    ),
    'access callback' => 'certificate_can_access_certificate',
    'access arguments' => array(
      1,
    ),
    'file' => 'certificate.pages.inc',
    'type' => MENU_LOCAL_TASK,
  );
  return $items;
}

/**
 * Implements hook_menu_alter().
 *
 * Move the Entity UI-created menu item to a local task.
 */
function certificate_menu_alter(&$items) {
  $items['admin/structure/certificates/snapshots']['title'] = 'Snapshots';
  $items['admin/structure/certificates/snapshots']['type'] = MENU_LOCAL_TASK;
}

/**
 * Implements hook_permission().
 */
function certificate_permission() {
  return array(
    'administer certificates' => array(
      'title' => t('administer certificates'),
      'description' => t('Configure global certificate settings and mappings.'),
    ),
    'administer certificate snapshots' => array(
      'title' => t('administer certificate snapshots'),
      'description' => t('Administer certificate snapshots via views'),
    ),
    'assign certificates' => array(
      'title' => t('assign certificates'),
      'description' => t('Add or remove certificate mappings on certifiable objects.'),
    ),
    'view all user certificates' => array(
      'title' => t('view all user certificates'),
      'description' => t('View any certificate earned by another user.'),
    ),
  );
}

/**
 * Implements hook_theme().
 *
 * Returns information about every themable function defined by the module.
 */
function certificate_theme() {
  $items = array();
  $items['certificate_certificate'] = array(
    'variables' => array(
      'node' => NULL,
      'account' => NULL,
      'template' => NULL,
    ),
    'file' => 'certificate.pages.inc',
  );
  $items['certificate_admin_clear_form'] = array(
    'render element' => 'form',
    'file' => 'certificate.admin.inc',
  );
  return $items;
}

/**
 * Public loader function for the full collection of certificates.
 * @return
 *   An array of all certificates, keyed by certificate ID.
 */
function certificate_certificate_load_all() {
  return entity_load('certificate');
}

/**
 * Implements hook_form_alter().
 *
 * Add certifiable checkbox to a content type.
 */
function certificate_form_alter(&$form, &$form_state, $form_id) {
  if ($form_id == 'node_type_form') {
    $form['certificate'] = array(
      '#type' => 'fieldset',
      '#title' => 'Certificate settings',
      '#collapsed' => TRUE,
      '#collapsible' => TRUE,
      '#group' => 'additional_settings',
    );
    $form['certificate']['certificate_certifiable'] = array(
      '#type' => 'checkbox',
      '#title' => 'Award certificate',
      '#description' => t('Make this content type certificate-enabled. Certificate mapping selections will show on the node form.'),
      '#default_value' => variable_get("certificate_certifiable_{$form['#node_type']->type}", 0),
    );
    if ($form['#node_type']->type == 'certificate') {
      $form['#after_build'][] = 'certificate_warn_course_content';
    }
  }
}

/**
 * Modify the node type form to add a warning about using a Certificate node as
 * a course content object.
 */
function certificate_warn_course_content(&$form, &$form_state) {
  if (module_exists('course_content')) {
    $form['course']['course_content_use']['#description'] = '<span class="error">This is probably not what you want! Do not use a Certificate as a course content object.<br/>Use the "Course certificate" module which provides a "Certificate" course object.</span>';
  }
  return $form;
}

/**
 * Implements hook_field_attach_form().
 */
function certificate_field_attach_form($entity_type, $entity, &$form, &$form_state, $langcode) {
  if ($entity_type == 'node' && certificate_node_is_certifiable($entity)) {

    // Add per-node certificate settings.
    module_load_include('inc', 'certificate', 'certificate.admin');
    certificate_alter_node_form($form, $form_state);
  }
}

/**
 * Submit handler to update mappings.
 */
function certificate_update_node_mappings($nid, array $node_settings = NULL) {
  if (is_array($node_settings)) {
    foreach ($node_settings as $mapper => $values) {
      foreach ($values as $match => $cert_nid) {
        if ($cert_nid) {
          $record = array(
            'nid' => $nid,
            'mapper' => $mapper,
            'type' => $match,
            'template' => $cert_nid,
          );
          db_merge('certificate_node')
            ->fields($record)
            ->key(array(
            'nid' => $nid,
            'mapper' => $mapper,
            'type' => $match,
          ))
            ->execute();
        }
        else {

          // No certificate has been set.
          // Delete any prior setting.
          db_delete('certificate_node')
            ->condition('nid', $nid)
            ->condition('mapper', $mapper)
            ->condition('type', $match)
            ->execute();
        }
      }
    }
  }
}

/**
 * Implementation of hook_node_insert().
 */
function certificate_node_insert($node) {
  certificate_node_update($node);
}

/**
 * Implementation of hook_node_update().
 */
function certificate_node_update($node) {
  if (certificate_node_is_certifiable($node)) {

    //** @kludge two update points here */

    // Update node mappings from a certifiable activity.
    if (!empty($node->certificate['map'])) {

      // Update from a node form.
      certificate_update_node_mappings($node->nid, $node->certificate['map']);
    }
    else {
      if (!empty($node->certificate['node_settings'])) {

        // Update programmatically.
        certificate_update_node_mappings($node->nid, $node->certificate['node_settings']);
      }
    }
  }
  if ($node->type == 'certificate') {

    // Save the certificate settings.
    if (isset($node->certificate)) {
      $record = $node->certificate;
      $record['nid'] = $node->nid;
      $keys = db_query("SELECT 1 FROM {certificate_node_settings} WHERE nid = :nid", array(
        ':nid' => $node->nid,
      ))
        ->fetchField() ? array(
        'nid',
      ) : array();
      drupal_write_record('certificate_node_settings', $record, $keys);
    }
  }
}

/**
 * Implements hook_nodeapi().
 */
function certificate_node_delete($node) {
  db_delete('certificate_node')
    ->condition('nid', $node->nid)
    ->execute();
  db_delete('certificate_snapshots')
    ->condition('nid', $node->nid)
    ->execute();
}

/**
 * Implements hook_node_load().
 */
function certificate_node_load($nodes, $types) {
  $query = db_query("SELECT * FROM {certificate_node} WHERE nid IN (:nids)", array(
    ':nids' => array_keys($nodes),
  ));
  while ($row = $query
    ->fetch()) {
    $nodes[$row->nid]->certificate['node_settings'][$row->mapper][$row->type] = $row->template;
  }
}

/**
 * Implements hook_node_view().
 */
function certificate_node_view($node, $view_mode, $langcode) {
  if (certificate_can_access_certificate($node)) {

    // Add a download certificate link to the node content.
    $node->content['certificate']['#markup'] = '<span class="certificate-link">' . l(t('Download certificate'), "node/{$node->nid}/certificate") . '</span>';
  }
}

/**
 * Implements hook_field_extra_fields().
 */
function certificate_field_extra_fields() {
  $extra = array();
  foreach (entity_get_info() as $entity_type => $entity_info) {
    if ($entity_type == 'node') {
      foreach (array_keys($entity_info['bundles']) as $bundle) {
        if (variable_get('certificate_certifiable_' . $bundle)) {
          $extra[$entity_type][$bundle]['form']['certificate'] = array(
            'label' => t('Certificate'),
            'description' => t('Certificate module elements'),
            'weight' => 0,
          );
        }
      }
    }
  }
  foreach (entity_get_info() as $entity_type => $entity_info) {
    if ($entity_type == 'certificate') {
      foreach (array_keys($entity_info['bundles']) as $bundle) {
        $extra[$entity_type][$bundle]['form']['title'] = array(
          'label' => t('Certificate title'),
          'description' => t('Certificate title'),
          'weight' => 1,
        );
        $extra[$entity_type][$bundle]['form']['name'] = array(
          'label' => t('Certificate machine name'),
          'description' => t('Certificate machine name'),
          'weight' => 2,
        );
        $extra[$entity_type][$bundle]['form']['orientation'] = array(
          'label' => t('Certificate orientation'),
          'description' => t('Certificate orientation'),
          'weight' => 3,
        );
        $extra[$entity_type][$bundle]['form']['certificate_tokens'] = array(
          'label' => t('Certificate tokens'),
          'description' => t('Tokens to insert into the certificate'),
          'weight' => 5,
        );
      }
    }
  }
  return $extra;
}

/**
 * Check if node is certifiable.
 *
 * @return bool
 */
function certificate_node_is_certifiable($node) {
  if (isset($node->type)) {
    return variable_get("certificate_certifiable_{$node->type}", 0);
  }
  return FALSE;
}

/**
 * Quick certificates snapshot check.
 *
 * @param $account
 *   The account.
 * @param $node
 *   The node.
 * @param $cid
 *   The certificate ID to check.
 *
 * @return
 *   A single certificate snapshot in array format, or FALSE if none matched the incoming ID.
 */
function certificate_snapshot_load($account, $node, $cid) {

  // Pull the certificate snapshot.
  // Note that a pre-7002 snapshot, since we do not know which certificate was snapshotted, will return the existing snapshot.
  $result = db_query("SELECT * FROM {certificate_snapshots} WHERE uid = :uid AND nid = :nid AND (cid = '0' OR cid = :cid)", array(
    ':uid' => $account->uid,
    ':nid' => $node->nid,
    ':cid' => $cid,
  ));
  return $result
    ->fetch(PDO::FETCH_ASSOC);
}

/**
 * Inserts a new snapshot, or updates an existing one.
 *
 * @param $certificate
 *   A certificate to be saved. If $certificate['cid'] is set, the certificate will be updated.
 *   Otherwise, a new certificate will be inserted into the database.
 * @return
 *   The saved certificate, with its ID set.
 *
 * @see certificate_single()
 */
function certificate_snapshot_save($snapshot) {
  if (isset($snapshot['csid'])) {
    drupal_write_record('certificate_snapshots', $snapshot, 'csid');
  }
  else {
    drupal_write_record('certificate_snapshots', $snapshot);
  }
  return $snapshot;
}

/**
 * Remove snapshot.
 *
 * @param stdClass $account
 * @param stdClass $node
 *
 * @return bool
 */
function certificate_snapshot_delete($account, $node) {
  $sql = "DELETE FROM {certificate_snapshots} WHERE uid = %d AND nid = %d";
  db_delete('certificate_snapshots')
    ->condition('uid', $account->uid)
    ->condition('nid', $node->nid)
    ->execute();
  return TRUE;
}

/**
 * Delete all snapshots on a node.
 *
 * @param stdClass $node
 *
 * @return bool
 */
function certificate_snapshot_delete_by_node($node) {
  $sql = "DELETE FROM {certificate_snapshots} WHERE nid = %d";
  db_delete('certificate_snapshots')
    ->condition('nid', $node->nid)
    ->execute();
  return TRUE;
}

/**
 * Implements hook_action_info().
 */
function certificate_action_info() {
  $info = array();
  $info['certificate_reset_certificates_action'] = array(
    'type' => 'node',
    'label' => t('Reset certificate snapshots for this node.'),
    'configurable' => FALSE,
    'triggers' => array(
      'nodeapi_insert',
      'nodeapi_update',
    ),
  );
  return $info;
}

/**
 * Expose certificate awarding as an action.
 */
function certificate_rules_action_info() {
  $info = array();
  $info['certificate_rules_award_certificate'] = array(
    'label' => t('Award certificate'),
    'configurable' => FALSE,
    'module' => 'certificate',
  );
  return $info;
}

/**
 * Set the awarded certificate.
 *
 * @todo in Drupal 7 and Rules 2, we can use return values. Rules 1 does not
 * have return values.
 */
function certificate_rules_award_certificate($node, $user) {
  global $_certificate_award;
  $_certificate_award = TRUE;
}

/**
 * Action to delete certificate snapshots on a node.
 */
function certificate_reset_certificates_action($object, $context) {
  $node = $object;
  if ($node->nid && is_numeric($node->nid)) {
    certificate_snapshot_delete_by_node($node);
    watchdog('action', 'Reset certificate snapshots for: %node.', array(
      '%node' => $node->title,
    ));
  }
}

/**
 * Check if a user can access a certificate for this node.
 *
 * This function:
 *  @return TRUE if certificate tab should show and be accessible.
 *  @return string (eval to true for Drupal's menu) if certificate tab should
 *    show but be denied with a message.
 *  @return FALSE if certificate tab should be hidden.
 */
function certificate_can_access_certificate($node, $account = NULL, $flush = FALSE) {
  static $cert_access = array();
  $found_true = NULL;
  $found_false = NULL;
  $admin = user_access('administer certificates');
  $view_all = user_access('view all user certificates');

  // Use account of a different user if allowed.
  if (($admin || $view_all) && arg(3) > 0) {
    $account = user_load(arg(3));
  }
  if (!$account) {
    global $user;
    $account = $user;
  }
  if (!$account->uid) {
    return FALSE;
  }
  if (!certificate_node_is_certifiable($node)) {
    return FALSE;
  }
  if ($flush || !isset($cert_access[$node->nid])) {
    $access = module_invoke_all('access_certificate', $node, $account);
    $cert_access[$node->nid] = $access;
  }
  else {
    $access = $cert_access[$node->nid];
  }
  foreach ($access as $item) {
    if ($item === TRUE) {

      // Something said the leaner should access the certificate.
      $found_true = TRUE;
    }
    if (is_string($item)) {

      // Something returned a string, return it (will show the menu, but error)
      return $item;
    }
    if ($item === FALSE) {
      $found_false = TRUE;
    }
  }
  if ($found_true) {
    if ($found_false) {

      // Found TRUE and FALSEs.
      return FALSE;
    }

    // Only found TRUE.
    return TRUE;
  }

  // All were false.
  return FALSE;
}

/**
 * Implements hook_user_cancel().
 */
function certificate_user_delete($account) {
  $sql = "DELETE FROM {certificate_snapshots} WHERE uid = :uid";
  db_query($sql, array(
    ':uid' => $account->uid,
  ));
}

/**
 * Return an array of certificate templates suitable for use in an options
 * form element.
 */
function certificate_get_template_options() {

  // Get existing templates.
  $templates = certificate_certificate_load_all();
  foreach ($templates as $key => $template) {
    $template_options[$key] = $template['title'];
  }
  return $template_options;
}

/**
 * Implements hook_certificate_map_options().
 *
 * Provide a list of options to the user that can be mapped to certificate
 * templates.
 *
 * @return Array of mapping sets.
 */
function certificate_certificate_map_options() {
  $options = array();
  if (module_exists('rules')) {
    $rules = array();
    foreach (rules_get_components() as $key => $ruleset) {
      if (array_search('certificate', $ruleset->tags) !== FALSE) {
        $rules[$key] = $ruleset->label;
      }
    }
    $options['rules'] = array(
      'title' => t('Rules'),
      'options' => $rules,
      'description' => t('When a rule or ruleset ends with "Award certificate", the selected certificate will be awarded.'),
    );
  }
  $fieldgroups = variable_get('certificate_field_groups', array());
  if (!empty($fieldgroups)) {
    $options['profile'] = array(
      'title' => t('Profiles'),
      'options' => $fieldgroups,
      'description' => t("If the user's profile matches a value in a field group, the selected certificate will be awarded."),
    );
  }
  $options['manual'] = array(
    'title' => t('Manual'),
    'description' => t('Select a single certificate to award to the user.'),
    'options' => array(
      'manual' => 'Manual',
    ),
  );
  return $options;
}

/**
 * Implements hook_certificate_map().
 *
 * Return the key of the mapping to use.
 *
 * @return string
 *   Key of matched mapping.
 */
function certificate_certificate_map($node, $user, $map_type, $options) {
  if ($map_type == 'rules') {
    foreach ($options as $key) {
      global $_certificate_award;
      $_certificate_award = FALSE;
      rules_invoke_component($key, $node, $user);
      if ($_certificate_award) {
        $valid[] = $key;
      }
    }
    return $valid;
  }
  if ($map_type == 'profile') {
    $profiles = module_exists('profile2') ? profile2_load_by_user($user) : array();
    $profiles['user'] = entity_load_single('user', $user->uid);
    $groupings = variable_get('certificate_field_grouping', array());
    foreach ($options as $key) {
      if (!empty($groupings[$key])) {
        foreach ($groupings[$key] as $field_name => $accepted_values) {
          foreach ($profiles as $profile) {
            if (!empty($profile->{$field_name}[LANGUAGE_NONE])) {
              foreach ($profile->{$field_name}[LANGUAGE_NONE] as $item) {
                if (in_array($item['value'], $accepted_values)) {
                  $valid[] = $key;
                }
              }
            }
          }
        }
      }
    }
    return $valid;
  }
  if ($map_type == 'manual') {
    if (isset($options[0]) && $options[0] == 'manual') {
      return 'manual';
    }
  }
}

/**
 * Implements hook_coder_ignore().
 */
function certificate_coder_ignore() {
  return array(
    'path' => drupal_get_path('module', 'certificate'),
    'line prefix' => drupal_get_path('module', 'certificate'),
  );
}

/**
 * Certificate Entity Support
 */
function certificate_entity_info() {
  $entities = array();
  if (db_table_exists('certificate')) {
    $entities['certificate'] = array(
      'label' => 'Certificate',
      'base table' => 'certificate',
      'revision table' => 'certificate_revision',
      'entity class' => 'Entity',
      'controller class' => 'EntityAPIControllerExportable',
      'fieldable' => TRUE,
      'exportable' => TRUE,
      'label callback' => 'certificate_entity_info_label',
      'bundles' => array(),
      'bundle keys' => array(
        'bundle' => 'type',
      ),
      'entity keys' => array(
        'id' => 'cid',
        'bundle' => 'type',
        'revision' => 'vid',
        'label' => 'title',
        'name' => 'name',
      ),
      'module' => 'certificate',
      'access callback' => 'certificate_access',
      'views controller class' => 'EntityDefaultViewsController',
      'admin ui' => array(
        'file' => 'certificate.module',
        'path' => 'admin/structure/certificates',
        'controller class' => 'CertificateEntityUIController',
      ),
    );
  }
  if (db_table_exists('certificate_snapshots')) {
    $entities['certificate_snapshot'] = array(
      'label' => 'Certificate snapshot',
      'base table' => 'certificate_snapshots',
      // 'revision table' => 'certificate_revision',
      'entity class' => 'Entity',
      'controller class' => 'EntityAPIController',
      'fieldable' => TRUE,
      'exportable' => FALSE,
      'label callback' => 'certificate_snapshot_entity_info_label',
      'entity keys' => array(
        'id' => 'csid',
      ),
      'module' => 'certificate',
      'access callback' => 'certificate_snapshot_access',
      'views controller class' => 'EntityDefaultViewsController',
      'admin ui' => array(
        'file' => 'certificate.module',
        'path' => 'admin/structure/certificates/snapshots',
        'controller class' => 'EntityDefaultUIController',
      ),
    );
  }
  if (db_table_exists('certificate_type')) {
    $entities['certificate_type'] = array(
      'label' => t('Certificate type'),
      'entity class' => 'Entity',
      'plural label' => t('Certificate types'),
      'description' => t('Certificate types.'),
      'controller class' => 'EntityAPIControllerExportable',
      'base table' => 'certificate_type',
      'fieldable' => FALSE,
      'entity class' => 'Entity',
      'bundle of' => 'certificate',
      'exportable' => TRUE,
      'entity keys' => array(
        'id' => 'id',
        'name' => 'type',
        'label' => 'label',
      ),
      'access callback' => 'certificate_type_access',
      'module' => 'course',
      // Enable the entity API's admin UI.
      'admin ui' => array(
        'file' => 'certificate.module',
        'path' => 'admin/structure/certificate-types',
        'controller class' => 'EntityDefaultUIController',
      ),
    );

    // Populate our bundles.
    $types = db_select('certificate_type', 'ct')
      ->fields('ct')
      ->execute()
      ->fetchAllAssoc('type');
    foreach ($types as $type => $info) {
      $entities['certificate']['bundles'][$type] = array(
        'label' => $info->label,
        'admin' => array(
          'path' => 'admin/structure/certificate-types/manage/%certificate_type',
          'real path' => 'admin/structure/certificate-types/manage/' . $type,
          'bundle argument' => 4,
          'access arguments' => array(
            'administer certificate',
          ),
        ),
      );
    }
  }
  return $entities;
}

/**
 * Load a single certificate by ID or name.
 *
 * Wrapper around entity_load_single().
 *
 * @param mixed
 *   A certificate ID or name.
 */
function certificate_load_single($name) {
  return entity_load_single('certificate', $name);
}

/**
 * Certificate Entity Access callback
 */
function certificate_access() {
  return user_access('administer certificates');
}

/**
 * Certificate snapshot Entity Access callback
 */
function certificate_snapshot_access() {
  return user_access('administer certificate snapshots');
}

/**
 * Implements hook_entity_presave().
 *
 * Set this newly saved revision as the active revision.
 */
function certificate_certificate_presave($entity) {
  if (!isset($entity->created)) {
    $entity->created = REQUEST_TIME;
  }
  $entity->changed = REQUEST_TIME;
  $entity->is_new_revision = TRUE;
  $entity->default_revision = TRUE;
}
function certificate_type_access() {
  return user_access('administer certificate types');
}
function certificate_type_form($form, &$form_state, $certificate_type, $op = 'edit') {
  if ($op == 'clone') {
    $certificate_type->label .= ' (cloned)';
    $certificate_type->type = '';
  }
  $form['label'] = array(
    '#title' => t('Label'),
    '#type' => 'textfield',
    '#default_value' => isset($certificate_type->label) ? $certificate_type->label : '',
    '#description' => t('The human-readable name of this certificate type.'),
    '#required' => TRUE,
    '#size' => 30,
  );

  // Machine-readable type name.
  $form['type'] = array(
    '#type' => 'machine_name',
    '#default_value' => isset($certificate_type->type) ? $certificate_type->type : '',
    '#maxlength' => 32,
    '#disabled' => !isset($certificate_type->is_new) && $op != 'clone',
    '#machine_name' => array(
      'exists' => 'certificate_types',
      'source' => array(
        'label',
      ),
    ),
    '#description' => t('A unique machine-readable name for this certificate type. It must only contain lowercase letters, numbers, and underscores.'),
  );
  $form['actions'] = array(
    '#type' => 'actions',
  );
  $form['actions']['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Save certificate type'),
    '#weight' => 40,
  );
  return $form;
}
function certificate_types($type_name = NULL) {
  $types = entity_load_multiple_by_name('certificate_type', isset($type_name) ? array(
    $type_name,
  ) : FALSE);
  return isset($type_name) ? reset($types) : $types;
}

/**
 * Form API submit callback for the type form.
 */
function certificate_type_form_submit(&$form, &$form_state) {
  $enrollment_type = entity_ui_form_submit_build_entity($form, $form_state);

  // Save and go back.
  $enrollment_type
    ->save();
  $form_state['redirect'] = 'admin/structure/certificate-types';
}
function certificate_type_load($type) {
  return certificate_types($type);
}

/**
 * Entity label callback.
 *
 * Provide a custom label for better UX.
 */
function certificate_snapshot_entity_info_label($entity, $entity_type) {
  $certificate = entity_load_single('certificate', $entity->cid);
  $acct = user_load($entity->uid);
  $course = course_load($entity->nid);
  $tokens = array(
    '!title' => $certificate ? $certificate->title : 'None',
    '!nid' => $course->nid,
    '!node_type' => $course->type,
    '!name' => $acct ? $acct->name : t('Missing user !uid', array(
      '!uid' => $entity->uid,
    )),
    '!mail' => $acct ? $acct->mail : NULL,
    '!date' => format_date($entity->date, 'custom', 'c'),
  );
  $label = t('!name !mail in !node_type !nid using template !title (!date)', $tokens);
  return $label;
}

/**
 * Implements hook_entity_property_info_alter().
 *
 * Define our special schema fields and relationships.
 */
function certificate_entity_property_info_alter(&$info) {
  $info['certificate_snapshot']['properties']['cid']['type'] = 'certificate';
  $info['certificate_snapshot']['properties']['uid']['type'] = 'user';
  $info['certificate_snapshot']['properties']['nid']['type'] = 'node';
  $info['certificate_snapshot']['properties']['date']['type'] = 'date';
  $info['certificate_snapshot']['properties']['snapshot']['type'] = 'text';
}

/**
 * Snapshot preview form.
 *
 * @param type $form
 * @param type $form_state
 * @param type $entity
 *
 * @return array
 */
function certificate_snapshot_form($form, &$form_state, $entity = NULL) {
  $form['snapshot_title'] = array(
    '#type' => 'item',
    '#markup' => '<h2>' . $entity
      ->label() . '</h2>',
  );
  $form['snapshot_html'] = array(
    '#type' => 'item',
    '#title' => t('Rendered snapshot'),
    '#markup' => isset($entity->snapshot) ? $entity->snapshot : '',
  );
  $form['actions'] = array(
    '#type' => 'actions',
  );
  $form['actions']['cancel'] = array(
    '#markup' => l(t('Return'), 'admin/structure/certificates/snapshots'),
  );
  return $form;
}

/**
 * Implements hook_views_api().
 */
function certificate_views_api() {
  return array(
    'api' => 3,
    'path' => drupal_get_path('module', 'certificate') . '/views',
  );
}

Functions

Namesort descending Description
certificate_access Certificate Entity Access callback
certificate_action_info Implements hook_action_info().
certificate_can_access_certificate Check if a user can access a certificate for this node.
certificate_certificate_load_all Public loader function for the full collection of certificates.
certificate_certificate_map Implements hook_certificate_map().
certificate_certificate_map_options Implements hook_certificate_map_options().
certificate_certificate_presave Implements hook_entity_presave().
certificate_coder_ignore Implements hook_coder_ignore().
certificate_entity_info Certificate Entity Support
certificate_entity_property_info_alter Implements hook_entity_property_info_alter().
certificate_field_attach_form Implements hook_field_attach_form().
certificate_field_extra_fields Implements hook_field_extra_fields().
certificate_form Certificate node form.
certificate_form_alter Implements hook_form_alter().
certificate_form_submit Certificate node form submit
certificate_get_template_options Return an array of certificate templates suitable for use in an options form element.
certificate_load_single Load a single certificate by ID or name.
certificate_menu Implements hook_menu().
certificate_menu_alter Implements hook_menu_alter().
certificate_node_delete Implements hook_nodeapi().
certificate_node_insert Implementation of hook_node_insert().
certificate_node_is_certifiable Check if node is certifiable.
certificate_node_load Implements hook_node_load().
certificate_node_update Implementation of hook_node_update().
certificate_node_view Implements hook_node_view().
certificate_permission Implements hook_permission().
certificate_reset_certificates_action Action to delete certificate snapshots on a node.
certificate_rules_action_info Expose certificate awarding as an action.
certificate_rules_award_certificate Set the awarded certificate.
certificate_snapshot_access Certificate snapshot Entity Access callback
certificate_snapshot_delete Remove snapshot.
certificate_snapshot_delete_by_node Delete all snapshots on a node.
certificate_snapshot_entity_info_label Entity label callback.
certificate_snapshot_form Snapshot preview form.
certificate_snapshot_load Quick certificates snapshot check.
certificate_snapshot_save Inserts a new snapshot, or updates an existing one.
certificate_theme Implements hook_theme().
certificate_types
certificate_type_access
certificate_type_form
certificate_type_form_submit Form API submit callback for the type form.
certificate_type_load
certificate_update_node_mappings Submit handler to update mappings.
certificate_user_delete Implements hook_user_cancel().
certificate_views_api Implements hook_views_api().
certificate_warn_course_content Modify the node type form to add a warning about using a Certificate node as a course content object.