'Taxonomy Publisher', 'description' => 'Configure which vocabularies will use Taxonomy Publisher.', 'page callback' => 'drupal_get_form', 'page arguments' => array('taxonomy_tools_publisher_admin_form'), 'access arguments' => array('administer taxonomy publisher configuration'), 'file' => 'taxonomy_tools_publisher.admin.inc', 'file path' => drupal_get_path('module', 'taxonomy_tools_publisher'), ); return $items; } /** * Implements hook_form_FORM_ID_alter(). */ function taxonomy_tools_publisher_form_taxonomy_form_term_alter(&$form, &$form_state) { $config = array_filter(variable_get('taxonomy_tools_publisher_config', array())); if (!empty($config) && in_array($form['#vocabulary']->machine_name, $config)) { // Only for terms that are from vocabularies that use Taxonomy Publisher. if (user_access('administer term schedule')) { // Add js files that adds custom controls for jQuery datepicker. $form['#attached']['js'][] = array( 'data' => 'http://datejs.googlecode.com/files/date.js', 'type' => 'external', ); // Datepicker localization. global $language; if ($language->language != 'en') { $form['#attached']['js'][] = drupal_get_path('module', 'jquery_update') . '/replace/ui/ui/i18n/jquery.ui.datepicker-' . $language->language . '.js'; } $form['#attached']['js'][] = drupal_get_path('module', 'taxonomy_tools_publisher') . '/js/taxonomy_tools_publisher.js'; // Add additional validation function. $form['#validate'][] = 'taxonomy_tools_publisher_taxonomy_term_form_validate'; // Add buttons for clearing date values. if (isset($form['field_taxonomy_term_publish_on'])) { $form['field_taxonomy_term_publish_on']['#suffix'] = ''; } if (isset($form['field_taxonomy_term_unpublish_on'])) { $form['field_taxonomy_term_unpublish_on']['#suffix'] = ''; } // Checkbox default value when date fields are available but no values // exist in database; happens when editing terms from vocabulary for // which Taxonomy Publisher was enabled when terms already exist in it. if (empty($form_state['build_info']['args'][0]->field_taxonomy_term_status)) { $form['field_taxonomy_term_status'][LANGUAGE_NONE]['#default_value'] = TERM_PUBLISHED; } } else { // User is not allowed to use taxonomy scheduler. $form['field_taxonomy_term_status']['#access'] = FALSE; $form['field_taxonomy_term_publish_on']['#access'] = FALSE; $form['field_taxonomy_term_unpublish_on']['#access'] = FALSE; } } } /** * Validates the user input of Taxonomy Publisher fields. * * @see taxonomy_tools_publisher_form_taxonomy_form_term_alter() */ function taxonomy_tools_publisher_taxonomy_term_form_validate($form, &$form_state) { if (!empty($form_state['values']['field_taxonomy_term_publish_on'][LANGUAGE_NONE][0]['value'])) { $publish_on = $form_state['values']['field_taxonomy_term_publish_on'][LANGUAGE_NONE][0]['value']; if ($publish_on < REQUEST_TIME) { // Publish on value must be in future. form_set_error('field_taxonomy_term_publish_on', t('The "Publish on:" date must be in the future.')); } } if (!empty($form_state['values']['field_taxonomy_term_unpublish_on'][LANGUAGE_NONE][0]['value'])) { $unpublish_on = $form_state['values']['field_taxonomy_term_unpublish_on'][LANGUAGE_NONE][0]['value']; if ($unpublish_on < REQUEST_TIME) { // Unpublish on value must be in future. form_set_error('field_taxonomy_term_unpublish_on', t('The "Unpublish on:" date must be in the future.')); } } if (isset($publish_on) && isset($unpublish_on) && $publish_on > $unpublish_on) { // Unpublish on value must be after publish on value. form_set_error('field_taxonomy_term_unpublish_on', t('The "Unpublish on:" date must be later than the "Publish on;" date.')); } } /** * Implements hook_taxonomy_term_presave(). */ function taxonomy_tools_publisher_taxonomy_term_presave($term) { if (in_array($term->vocabulary_machine_name, array_filter(variable_get('taxonomy_tools_publisher_config', array())))) { // Clear unpublish value if term status is set to unpublished and // publish value is not set. if (isset($term->field_taxonomy_term_status) && $term->field_taxonomy_term_status[LANGUAGE_NONE][0]['value'] == TERM_NOT_PUBLISHED && isset($term->field_taxonomy_term_publish_on) && empty($term->field_taxonomy_term_publish_on[LANGUAGE_NONE]) && isset($term->field_taxonomy_term_unpublish_on) && !empty($term->field_taxonomy_term_unpublish_on[LANGUAGE_NONE])) { $term->field_taxonomy_term_unpublish_on[LANGUAGE_NONE] = array(); } // Set term status to unpublished if publish and unpublish values are set. if (isset($term->field_taxonomy_term_status) && $term->field_taxonomy_term_status[LANGUAGE_NONE][0]['value'] == TERM_PUBLISHED && isset($term->field_taxonomy_term_publish_on) && !empty($term->field_taxonomy_term_publish_on[LANGUAGE_NONE]) && isset($term->field_taxonomy_term_unpublish_on) && !empty($term->field_taxonomy_term_unpublish_on[LANGUAGE_NONE])) { $term->field_taxonomy_term_status[LANGUAGE_NONE][0]['value'] = TERM_NOT_PUBLISHED; } // Show term status message. if (isset($term->field_taxonomy_term_status)) { $message = ''; if ($term->field_taxonomy_term_status[LANGUAGE_NONE][0]['value'] == TERM_PUBLISHED) { $message .= t('The term @name is published.', array('@name' => $term->name)); if (isset($term->field_taxonomy_term_unpublish_on) && !empty($term->field_taxonomy_term_unpublish_on[LANGUAGE_NONE])) { $message .= ' '; $message .= t('It will be unpublished on @unpublish_on', array( '@unpublish_on' => format_date($term->field_taxonomy_term_unpublish_on[LANGUAGE_NONE][0]['value'], 'custom', TAXONOMY_PUBLISHER_MESSAGE_DATE_FORMAT)) ); } } else { $message .= t('The term @name is unpublished.', array('@name' => $term->name)); if (isset($term->field_taxonomy_term_publish_on) && !empty($term->field_taxonomy_term_publish_on[LANGUAGE_NONE])) { $message .= ' '; $message .= t('It will be published on @publish_on', array( '@publish_on' => format_date($term->field_taxonomy_term_publish_on[LANGUAGE_NONE][0]['value'], 'custom', TAXONOMY_PUBLISHER_MESSAGE_DATE_FORMAT)) ); } } drupal_set_message(check_plain($message)); } } } /** * Implements hook_cron(). */ function taxonomy_tools_publisher_cron() { // Publish terms. taxonomy_tools_publisher_publish(); // Allow other modules to act upon scheduled term publishing. module_invoke_all('taxonomy_tools_publisher_terms_publish'); // Unpublish terms. taxonomy_tools_publisher_unpublish(); // Allow other modules to act upon scheduled term publishing. module_invoke_all('taxonomy_tools_publisher_terms_unpublish'); } /** * Publishes scheduled taxonomy terms. */ function taxonomy_tools_publisher_publish() { // Collect term ID's of terms which publish on value is before now. $config = array_filter(variable_get('taxonomy_tools_publisher_config', array())); $query = db_select('field_data_field_taxonomy_term_publish_on', 'foo'); $query->addField('foo', 'entity_id', 'tid'); $query->addField('foo', 'field_taxonomy_term_publish_on_value', 'publish_on'); $query->leftJoin('taxonomy_term_data', 'bar', 'foo.entity_id = bar.tid'); $query->join('taxonomy_vocabulary', 'baz', 'baz.vid = bar.vid'); $query->condition('baz.machine_name', $config, 'IN'); $result = $query->execute()->fetchAll(); $tids = array(); foreach ($result as $data) { if ($data->publish_on < REQUEST_TIME) { $tids[] = $data->tid; } } foreach ($tids as $tid) { // Publish the term. taxonomy_tools_publisher_publish_term($tid); } } /** * Unpublishes scheduled taxonomy terms. */ function taxonomy_tools_publisher_unpublish() { // Collect term ID's of terms which publish on value is before now. $config = array_filter(variable_get('taxonomy_tools_publisher_config', array())); $query = db_select('field_data_field_taxonomy_term_unpublish_on', 'foo'); $query->addField('foo', 'entity_id', 'tid'); $query->addField('foo', 'field_taxonomy_term_unpublish_on_value', 'unpublish_on'); $query->leftJoin('taxonomy_term_data', 'bar', 'foo.entity_id = bar.tid'); $query->join('taxonomy_vocabulary', 'baz', 'baz.vid = bar.vid'); $query->condition('baz.machine_name', $config, 'IN'); $result = $query->execute()->fetchAll(); $tids = array(); foreach ($result as $data) { if ($data->unpublish_on < REQUEST_TIME) { $tids[] = $data->tid; } } foreach ($tids as $tid) { // Unpublish the term. taxonomy_tools_publisher_unpublish_term($tid); } } /** * Implements hook_permission(). */ function taxonomy_tools_publisher_permission() { return array( 'administer term schedule' => array( 'title' => t('Administer term schedule'), 'description' => t('User is able set scheduler times and change term status.'), ), 'bypass taxonomy publisher' => array( 'title' => t('Bypass Taxonomy Publisher settings'), 'description' => t('User is able to bypass restrictions set by Taxonomy Publisher.'), ), 'administer taxonomy publisher configuration' => array( 'title' => t('Administer Taxonomy Publisher configuration'), 'description' => t('User is able to access and use Taxonomy Publisher configuration page.'), ), ); } /** * Checks the taxonomy term and it's ancestors for availability. * * @param string $tid * A string containing taxonomy term ID. * * @return bool * TRUE if taxonomy term is published and none of it's parents is unpublished, * FALSE either if the taxonomy term itself or at least one of it's * parents is unpublished. */ function taxonomy_tools_publisher_check_branch($tid) { // Get term status value from DB. $query = db_select('field_data_field_taxonomy_term_status', 'foo'); $query->addField('foo', 'field_taxonomy_term_status_value', 'term_status'); $query->condition(db_and()->condition('foo.entity_id', $tid)->condition('entity_type', 'taxonomy_term')); $status_result = $query->execute()->fetchField(); // Term status is set to "Unpublished". if ($status_result !== FALSE && !$status_result) { $status = 0; } // Every other situation term is considered as "Published". else { $query = db_select('taxonomy_term_hierarchy', 'foo'); $query->addField('foo', 'parent'); $query->condition('foo.tid', $tid); $parent_result = $query->execute()->fetchField(); // If term has a parent it must also be checked for availability. if ($parent_result != 0) { $status = taxonomy_tools_publisher_check_branch($parent_result); } else { $status = 1; } } return $status; } /** * Implements hook_term_copy_alter(). */ function taxonomy_tools_publisher_term_copy_alter(&$term) { // Only for terms that are from a vocabulary that uses Taxonomy Publisher. if (in_array($term->vocabulary_machine_name, array_filter(variable_get('taxonomy_tools_publisher_config', array())))) { // Set the status to "unpublished". $term->field_taxonomy_term_status[LANGUAGE_NONE][0]['value'] = TERM_NOT_PUBLISHED; // No scheduling. $term->field_taxonomy_term_publish_on[LANGUAGE_NONE] = array(); $term->field_taxonomy_term_unpublish_on[LANGUAGE_NONE] = array(); } else { // Remove Taxonomy Publisher fields if destination vocabulary does // not use them. if (isset($term->field_taxonomy_term_status)) { unset($term->field_taxonomy_term_status); } if (isset($term->field_taxonomy_term_publish_on)) { unset($term->field_taxonomy_term_publish_on); } if (isset($term->field_taxonomy_term_unpublish_on)) { unset($term->field_taxonomy_term_unpublish_on); } } } /** * Returns term reference fields. * * @param string $bundle * Node type. */ function taxonomy_tools_publisher_reference_fields($bundle) { $fields = array(); // Get term reference fields. $query = db_select('field_config', 'fc'); $query->addField('fc', 'field_name'); $query->addField('fc', 'data'); $query->condition('fc.deleted', 0); $query->condition('fc.type', 'taxonomy_term_reference'); $query->join('field_config_instance', 'fci', 'fci.field_name = fc.field_name'); $query->condition('fci.entity_type', 'node'); $query->condition('fci.bundle', $bundle); $result = $query->execute()->fetchAll(); $vocabularies = array_filter(variable_get('taxonomy_tools_publisher_config', array())); foreach ($result as $key => $field) { $data = unserialize($field->data); if (in_array($data['settings']['allowed_values'][0]['vocabulary'], $vocabularies)) { $fields[] = $field->field_name; } } return $fields; } /** * Implements hook_node_update(). */ function taxonomy_tools_publisher_node_update($node) { $fields = taxonomy_tools_publisher_reference_fields($node->type); // Publish taxonomy terms that use this node. if (!empty($fields) && $node->status == 1 && variable_get('taxonomy_tools_publisher_automatic_publishing', 0) == 1) { foreach ($fields as $field) { $terms = $node->{$field}[LANGUAGE_NONE]; foreach ($terms as $term) { taxonomy_tools_publisher_publish_term($term['tid']); } } } } /** * Implements hook_node_insert(). */ function taxonomy_tools_publisher_node_insert($node) { $fields = taxonomy_tools_publisher_reference_fields($node->type); // Publish taxonomy terms that use this node. if (!empty($fields) && $node->status == 1 && variable_get('taxonomy_tools_publisher_automatic_publishing', 0) == 1) { foreach ($fields as $field) { $terms = $node->{$field}[LANGUAGE_NONE]; foreach ($terms as $term) { taxonomy_tools_publisher_publish_term($term['tid']); } } } } /** * Publishes taxonomy term. * * @param int $tid * Taxonomy term ID. */ function taxonomy_tools_publisher_publish_term($tid) { $term = taxonomy_term_load($tid); if ($term->field_taxonomy_term_status[LANGUAGE_NONE][0]['value'] == TERM_NOT_PUBLISHED) { // Set taxonomy term status to "Published". $term->field_taxonomy_term_status[LANGUAGE_NONE][0]['value'] = TERM_PUBLISHED; // Remove publish on time. if (!empty($term->field_taxonomy_term_publish_on)) { $term->field_taxonomy_term_publish_on = array(); } taxonomy_term_save($term); // Allow other modules to act upon term publishing. module_invoke_all('taxonomy_tools_publisher_term_publish', $term); } } /** * Unpublishes taxonomy term. * * @param int $tid * Taxonomy term ID. */ function taxonomy_tools_publisher_unpublish_term($tid) { $term = taxonomy_term_load($tid); if ($term->field_taxonomy_term_status[LANGUAGE_NONE][0]['value'] == TERM_PUBLISHED) { // Set taxonomy term status to "Unpublished". $term->field_taxonomy_term_status[LANGUAGE_NONE][0]['value'] = TERM_NOT_PUBLISHED; // Remove unpublish on time. if (!empty($term->field_taxonomy_term_publish_on)) { $term->field_taxonomy_term_unpublish_on = array(); } taxonomy_term_save($term); // Allow other modules to act upon term unpublishing. module_invoke_all('taxonomy_tools_publisher_term_unpublish', $term); } } /** * Implements hook_preprocess_html(). */ function taxonomy_tools_publisher_preprocess_html(&$variables) { if (arg(0) == 'taxonomy' && arg(1) == 'term' && is_numeric(arg(2))) { $term = taxonomy_term_load(arg(2)); $vocabularies = array_filter(variable_get('taxonomy_tools_publisher_config', array())); if (in_array($term->vocabulary_machine_name, $vocabularies)) { // Add a html class to the body depending on term status. if (!empty($term->field_taxonomy_term_status) && $term->field_taxonomy_term_status[LANGUAGE_NONE][0]['value'] == TERM_NOT_PUBLISHED) { $variables['classes_array'][] = check_plain('term-unpublished'); } else { $variables['classes_array'][] = check_plain('term-published'); } } } }