? maxlength_max_words.patch
Index: maxlength.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/maxlength/maxlength.install,v
retrieving revision 1.8
diff -u -p -r1.8 maxlength.install
--- maxlength.install	28 Sep 2008 13:07:38 -0000	1.8
+++ maxlength.install	27 May 2009 17:15:37 -0000
@@ -36,6 +36,8 @@ function maxlength_uninstall() {
     $code = MAXLENGTH_NODE_TYPE . $type;
     
     variable_del($code .'_t');
+    variable_del($code .'_tt');
     variable_del($code .'_b');
+    variable_del($code .'_bt');
   }
 }
Index: maxlength.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/maxlength/maxlength.module,v
retrieving revision 1.16
diff -u -p -r1.16 maxlength.module
--- maxlength.module	28 Sep 2008 13:07:38 -0000	1.16
+++ maxlength.module	27 May 2009 17:15:38 -0000
@@ -57,22 +57,48 @@ function _maxlength_admin_settings() {
       '#collapsed' => strlen(variable_get($code .'_t', '') . variable_get($code .'_b', '')) == 0,
     );
     
-    $form['nodetypes'][$type][$code .'_t'] = array(
+    $form['nodetypes'][$type]['title'] = array(
+      '#type' => 'fieldset',
+      '#title' => $type_info->title_label,
+      '#collapsible' => FALSE,
+    );
+    
+    $form['nodetypes'][$type]['title'][$code .'_t'] = array(
       '#type' => 'textfield',
       '#title' => t('!label Maxlength', array('!label' => $type_info->title_label)),
-      '#field_suffix' => t('characters'),
       '#return_value' => 1,
       '#default_value' => variable_get($code .'_t', ''),
-      '#description' => t('Maximum number of characters allowed for the title field of this content type. Leave blank for an unlimited size.'),
+      '#description' => t('Maximum number of characters or words allowed for the title field of this content type. Leave blank for an unlimited size.'),
+    );
+
+    $form['nodetypes'][$type]['title'][$code .'_tt'] = array(
+      '#type' => 'select',
+      '#title' => t('!label Limit Type', array('!label' => $type_info->title_label)),
+      '#options' => array('char' => t('Characters'), 'word' => t('Words')),
+      '#default_value' => variable_get($code .'_tt', 'char'),
+      '#description' => t('Choose whether to limit the title field size by characters or words.'),
+    );
+    
+    $form['nodetypes'][$type]['body'] = array(
+      '#type' => 'fieldset',
+      '#title' => $type_info->body_label,
+      '#collapsible' => FALSE,
     );
     
-    $form['nodetypes'][$type][$code .'_b'] = array(
+    $form['nodetypes'][$type]['body'][$code .'_b'] = array(
       '#type' => 'textfield',
       '#title' => t('!label Maxlength', array('!label' => $type_info->body_label)),
-      '#field_suffix' => t('characters'),
       '#return_value' => 1,
       '#default_value' => variable_get($code .'_b', ''),
-      '#description' => t('Maximum number of characters allowed for the body field of this content type. Leave blank for an unlimited size.'),
+      '#description' => t('Maximum number of characters or words allowed for the body field of this content type. Leave blank for an unlimited size.'),
+    );
+
+    $form['nodetypes'][$type]['body'][$code .'_bt'] = array(
+      '#type' => 'select',
+      '#title' => t('!label Limit Type', array('!label' => $type_info->body_label)),
+      '#options' => array('char' => t('Characters'), 'word' => t('Words')),
+      '#default_value' => variable_get($code .'_bt', 'char'),
+      '#description' => t('Choose whether to limit the body field size by characters or words.'),
     );
   }
 
@@ -85,9 +111,15 @@ function _maxlength_admin_settings() {
 function maxlength_elements() {
   $type = array();
   
-  if (_maxlength_limit_body()) {
+  $limit = _maxlength_limit_body();
+  if ($limit == 'char') {
+    $type['textarea'] = array(
+      '#theme' => 'maxlength_textarea_characters',
+    );
+  }
+  elseif ($limit == 'word') {
     $type['textarea'] = array(
-      '#theme' => 'maxlength_textarea',
+      '#theme' => 'maxlength_textarea_words',
     );
   }
   
@@ -99,31 +131,42 @@ function _maxlength_limit_body() {
     if (arg(1) == 'add') {
       $type = str_replace('-', '_', arg(2));
       
-      return strlen(variable_get(MAXLENGTH_NODE_TYPE . $type .'_b', '')) > 0;
+      if (strlen(variable_get(MAXLENGTH_NODE_TYPE . $type .'_b', '')) > 0) {
+        return variable_get(MAXLENGTH_NODE_TYPE . $type .'_bt', 'char');
+      }
     }
     
     if (arg(2) == 'edit') {
       $nid = intval(arg(1));
       
-      return strlen(variable_get(MAXLENGTH_NODE_TYPE . _maxlength_node_type_from_id($nid) .'_b', '')) > 0;
+      if (strlen(variable_get(MAXLENGTH_NODE_TYPE . _maxlength_node_type_from_id($nid) .'_b', '')) > 0) {
+        return variable_get(MAXLENGTH_NODE_TYPE . _maxlength_node_type_from_id($nid) .'_bt', 'char');
+      }
     }
   }
   
   return FALSE;
 }
+
 /**
  * Implementation of hook_theme().
  */ 
 function maxlength_theme(){
   return array(
-    'maxlength_textarea' => array(
+    'maxlength_textarea_characters' => array(
+      'arguments' => array(
+        'element' => array()
+      ),
+    ),
+    'maxlength_textarea_words' => array(
       'arguments' => array(
         'element' => array()
       ),
     ),
   );
 }
-function theme_maxlength_textarea($element) {
+
+function theme_maxlength_textarea_characters($element) {
   $prefix = '';
   
   if ($element['#name'] == 'body') {
@@ -164,6 +207,27 @@ function theme_maxlength_textarea($eleme
   return theme_textarea($element) . $prefix;
 }
 
+function theme_maxlength_textarea_words($element) {
+  $prefix = '';
+  
+  if ($element['#name'] == 'body') {
+    if (arg(1) == 'add') {
+      $type = str_replace('-', '_', arg(2));
+    }
+    else {
+      $type = _maxlength_node_type_from_id(intval(arg(1)));
+    }
+    
+    $limit = intval(variable_get(MAXLENGTH_NODE_TYPE . $type .'_b', ''));
+    
+    $remaining = $limit - (drupal_strlen($element['#value']) == 0 ? 0 : count(explode(' ', $element['#value'])));
+    
+    $prefix = t('<div id="maxlength-counter">Content limited to !limit words, remaining: <strong id="maxlength-counter-remaining">!remaining</strong></div>', array('!limit' => $limit, '!remaining' => $remaining));
+  }
+  
+  return theme_textarea($element) . $prefix;
+}
+
 function _maxlength_node_type_from_id($nid) {
   $node = node_load($nid);
   
@@ -177,7 +241,7 @@ function maxlength_form_alter(&$form, $f
   if (isset($form['type'])) {
     $type = $form['type']['#value'];
     if ( $type .'_node_form' == $form_id) {
-      if (strlen(variable_get(MAXLENGTH_NODE_TYPE . $type .'_t', '')) > 0) {
+      if ((variable_get(MAXLENGTH_NODE_TYPE . $type .'_tt', 'char') == 'char') && strlen(variable_get(MAXLENGTH_NODE_TYPE . $type .'_t', '')) > 0) {
         $limit = intval(variable_get(MAXLENGTH_NODE_TYPE . $type .'_t', ''));
         $form['title']['#maxlength'] = $limit;
         
@@ -208,13 +272,72 @@ function maxlength_nodeapi(&$node, $op, 
       case 'validate':
         $form = $a3;
         
+        // Check title word limit.
+        $limit = intval(variable_get($code .'_t', ''));
+
+        if (variable_get($code .'_tt', 'char') == 'word') {
+          if (count(explode(' ', $node->title)) > $limit) {
+            form_set_error('title', t('The maximum number of words in the title field has been exceeded!'));
+          }
+        }        
+        
+        // Check body char/word limit.
         $limit = intval(variable_get($code .'_b', ''));
         
-        if (drupal_strlen($node->body) > $limit) {
-          form_set_error('body', t('The maximum number of characters has been exceeded!'));
+        if (variable_get($code .'_bt', 'char') == 'char') {
+          if (drupal_strlen($node->body) > $limit) {
+            form_set_error('body', t('The maximum number of characters in the body field has been exceeded!'));
+          }
+        }        
+        elseif (variable_get($code .'_bt', 'char') == 'word') {
+          if (count(explode(' ', $node->body)) > $limit) {
+            form_set_error('body', t('The maximum number of words in the body field has been exceeded! Bodfy truncated to %limit words', array('%limit' => $limit)));
+            
+            // TODO: Truncate the body field. Commented code below doesn't do the job.
+            /*
+            $type_info = node_get_types('type', $node->type);
+            
+            $offset = 0;
+            for($i = 1; $i < $limit; $i++) {
+              $offset = strpos($node->body, ' ', $offset) + 1;
+            }
+            $form['body_field']['body']['#value'] = drupal_substr($node->body, 0, strpos($node->body, ' ', $offset));
+  
+            drupal_set_message(
+              t('%body_field_label truncated to %limit words!',
+              array(
+                '%body_field_label' => $type_info->body_label,
+                '%limit' => $limit)
+              ),
+              'error'
+            );
+            */
+          }
         }
-        
         break;
+
+//      case 'prepare':
+//        // Truncate body field.
+//        $limit = intval(variable_get($code .'_b', ''));
+//        if (variable_get($code .'_bt', 'char') == 'word' && (count(explode(' ', $node->body)) > $limit)) {
+//          $type_info = node_get_types('type', $node->type);
+//          
+//          $offset = 0;
+//          for($i = 1; $i < $limit; $i++) {
+//            $offset = strpos($node->body, ' ', $offset) + 1;
+//          }
+//          $node->body = drupal_substr($node->body, 0, strpos($node->body, ' ', $offset));
+//
+//          drupal_set_message(
+//            t('%body_field_label truncated to %limit words!',
+//            array(
+//              '%body_field_label' => $type_info->body_label,
+//              '%limit' => $limit)
+//            ),
+//            'error'
+//          );
+//        }
+//        break;
     }
   }
 }
@@ -228,7 +351,9 @@ function maxlength_node_type($op, $info)
       $code = MAXLENGTH_NODE_TYPE . $info->type;
       
       variable_del($code .'_t');
+      variable_del($code .'_tt');
       variable_del($code .'_b');
+      variable_del($code .'_bt');
       
       break;
     
@@ -238,13 +363,19 @@ function maxlength_node_type($op, $info)
         $code_new = MAXLENGTH_NODE_TYPE . $info->type;
         
         $max_title = variable_get($code_old .'_t', '');
+        $type_title = variable_get($code_old .'_tt', '');
         $max_body  = variable_get($code_old .'_b', '');
+        $type_body  = variable_get($code_old .'_bt', '');
         
         variable_set($code_new .'_t', $max_title);
+        variable_set($code_new .'_tt', $type_title);
         variable_set($code_new .'_b', $max_body);
+        variable_set($code_new .'_bt', $type_body);
         
         variable_del($code_old .'_t');
+        variable_del($code_old .'_tt');
         variable_del($code_old .'_b');
+        variable_del($code_old .'_bt');
       }
       
       break;
