'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');
}
}
}
}