type .'_node_form' == $form_id) { //this is a node form if (auto_nodetitle_get_setting($form['#node']->type) == AUTO_NODETITLE_ENABLED) { // we will autogenerate the title later, just hide the title field in the meanwhile $form['title']['#value'] = 'ant'; $form['title']['#type'] = 'value'; $form['title']['#required'] = FALSE; } else if (auto_nodetitle_get_setting($form['#node']->type) == AUTO_NODETITLE_OPTIONAL) { // we will make the title optional $form['title']['#required'] = FALSE; } } } /** * Implementation of hook_nodeapi(). * * Sets the node title. * To let node previews work this is also done during node validation. */ function auto_nodetitle_nodeapi(&$node, $op, $form = NULL, $a4 = NULL) { if ($op == 'validate' && $form['#post']['op'] == t('Preview') && auto_nodetitle_is_needed($node)) { // As changes to $node are not persistent during validation, we use form_set_value()! auto_nodetitle_set_title($node); form_set_value($form['title'], $node->title); } else if ($op == 'submit' && auto_nodetitle_is_needed($node)) { auto_nodetitle_set_title($node); } } /** * Returns whether the auto nodetitle has to be set. */ function auto_nodetitle_is_needed($node) { return empty($node->auto_nodetitle_applied) && ($setting = auto_nodetitle_get_setting($node->type)) && !($setting == AUTO_NODETITLE_OPTIONAL && !empty($node->title)); } /* * Sets the automatically generated nodetitle for the node */ function auto_nodetitle_set_title(&$node) { $types = node_get_types(); $pattern = variable_get('ant_pattern_'. $node->type, ''); if (trim($pattern)) { $node->changed = time(); $node->title = _auto_nodetitle_patternprocessor($pattern, $node); } else if ($node->nid) { $node->title = t('@type @node-id', array('@type' => $types[$node->type]->name, '@node-id' => $node->nid)); } else { $node->title = t('@type', array('@type' => $types[$node->type]->name)); } // Ensure the generated title isn't too long. $node->title = substr($node->title, 0, 255); // With that flag we ensure we don't apply the title two times to the same node. $node->auto_nodetitle_applied = TRUE; } /** * Implementation of hook_node_operations(). */ function auto_nodetitle_node_operations() { $operations = array( 'nodetitle_update' => array( 'label' => t('Update automatic nodetitles'), 'callback' => 'auto_nodetitle_operations_update', ), ); return $operations; } /** * Callback function for updating node titles. */ function auto_nodetitle_operations_update($nodes) { foreach ($nodes as $nid) { $node = node_load($nid); if ($node && auto_nodetitle_is_needed($node)) { $previous_title = $node->title; auto_nodetitle_set_title($node); // Only save if the title has actually changed. if ($node->title != $previous_title) { node_save($node); } } } } /** * Helper function to generate the title according to the PHP code. * Right now its only a wrapper, but if this is to be expanded, here is the place to be. * @return a title string */ function _auto_nodetitle_patternprocessor($output, $node) { if (module_exists('token')) { $output = token_replace($output, 'node', $node); } if (variable_get('ant_php_'. $node->type, 0)) { $output = auto_nodetitle_eval($output, $node); } if (variable_get('ant_php_'. $node->type, 0) || module_exists('token')) { $output = preg_replace('/[\t\n\r\0\x0B]/', '', strip_tags($output)); } return $output; } /** * Helper function for hook_form_alter() renders the settings per node-type. * @TODO: a re-evaluate PHP pattern on edit? option. */ function auto_nodetitle_node_settings_form(&$form) { $form['auto_nodetitle'] = array( '#type' => 'fieldset', '#title' => t('Automatic title generation'), '#weight' => 0, '#collapsible' => TRUE, '#collapsed' => TRUE, ); $form['auto_nodetitle']['ant'] = array( '#type' => 'radios', '#default_value' => auto_nodetitle_get_setting($form['#node_type']->type), '#options' => array( t('Disabled'), t('Automatically generate the title and hide the title field'), t('Automatically generate the title if the title field is left empty'), ) ); if (module_exists('token') || user_access('use PHP for title patterns')) { $description = t('Leave blank for using the per default generated title. Otherwise this string will be used as title.'); if (module_exists('token')) { $description .= ' '. t('Use the syntax [token] if you want to insert a replacement pattern.'); } $form['auto_nodetitle']['ant_pattern'] = array( '#type' => 'textarea', '#title' => t('Pattern for the title'), '#description' => $description, '#default_value' => variable_get('ant_pattern_'. $form['#node_type']->type, ''), ); // Don't allow editing of the pattern if PHP is used, but the users lacks // permission for PHP. if (variable_get('ant_php_' . $form['#node_type']->type, '') && !user_access('use PHP for title patterns')) { $form['auto_nodetitle']['ant_pattern']['#value'] = $form['auto_nodetitle']['ant_pattern']['#default_value']; $form['auto_nodetitle']['ant_pattern']['#disabled'] = TRUE; $form['auto_nodetitle']['ant_pattern']['#description'] = t('You are not allow the configure the pattern for the title, as you lack the %permission permission.', array('%permission' => t('Use PHP for title patterns'))); } } if (module_exists('token')) { $form['auto_nodetitle']['token_help'] = array( '#title' => t('Replacement patterns'), '#type' => 'fieldset', '#collapsible' => TRUE, '#collapsed' => TRUE, '#description' => t('Prefer raw-text replacements for text to avoid problems with HTML entities!'), ); $form['auto_nodetitle']['token_help']['help'] = array( '#value' => theme('token_help', 'node'), ); } if (user_access('use PHP for title patterns')) { $form['auto_nodetitle']['ant_php'] = array( '#type' => 'checkbox', '#title' => t('Evaluate PHP in pattern.'), '#description' => t('Put PHP code above that returns your string, but make sure you surround code in <?php and ?>. Note that $node is available and can be used by your code.'), '#default_value' => variable_get('ant_php_'. $form['#node_type']->type, ''), ); } else { $form['auto_nodetitle']['auto_nodetitle_php'] = array( '#type' => 'value', '#value' => variable_get('ant_php_'. $form['#node_type']->type, ''), ); } } /** * Gets the auto node title setting associated with the given content type. */ function auto_nodetitle_get_setting($type) { return variable_get('ant_'. $type, AUTO_NODETITLE_DISABLED); } /** * Evaluates php code and passes $node to it */ function auto_nodetitle_eval($code, $node) { ob_start(); print eval('?>'. $code); $output = ob_get_contents(); ob_end_clean(); return $output; } /** * Implementation of hook_node_type(). */ function auto_nodetitle_node_type($op, $info) { switch ($op) { case 'delete': variable_del('ant_'. $info->type); variable_del('ant_pattern_'. $info->type); variable_del('ant_php_'. $info->type); break; case 'update': if (!empty($info->old_type) && $info->old_type != $info->type) { variable_set('ant_'. $info->type, auto_nodetitle_get_setting($info->old_type)); variable_set('ant_pattern_'. $info->type, variable_get('ant_pattern_'. $info->old_type, '')); variable_set('ant_php_'. $info->type, variable_get('ant_php_'. $info->old_type, '')); variable_del('ant_'. $info->old_type); variable_del('ant_pattern_'. $info->old_type); variable_del('ant_php_'. $info->old_type); } break; } }