You are here

apachesolr_multilingual_textfile.module in Apache Solr Multilingual 6

File

apachesolr_multilingual_textfile/apachesolr_multilingual_textfile.module
View source
<?php

function apachesolr_multilingual_textfile_node_info() {
  return array(
    'apachesolr_multilingual_textfile' => array(
      'name' => 'Apache Solr Multilingual Textfile',
      'module' => 'apachesolr_multilingual_textfile',
      'description' => 'Create / edit a apache solr textfile (stopwords.txt, synonyms.txt, ...)',
      'title_label' => 'Create / edit a apache solr textfile (stopwords.txt, synonyms.txt, ...)',
      'has_body' => TRUE,
      'promote' => FALSE,
    ),
  );
}
function apachesolr_multilingual_textfile_theme() {
  return array(
    'apachesolr_multilingual_textfile_form_element' => array(
      'arguments' => array(
        'form' => NULL,
      ),
    ),
  );
}
function apachesolr_multilingual_textfile_form(&$node, $form_state) {
  $node->status = 0;

  // do not published
  $apachesolr_multilingual_filetypes = variable_get('apachesolr_multilingual_filetypes', array(
    'stopwords.txt' => 'stopwords.txt',
    'synonyms.txt' => 'synonyms.txt',
    'protwords.txt' => 'protwords.txt',
    'compoundwords.txt' => 'compoundwords.txt',
  ));

  // load / set the filenames
  $schema_source_path = dirname(__FILE__) . '/../resources/';

  // path to resources
  if ($node->filename && $node->language) {
    $node_auto_created = TRUE;
  }
  else {
    $node_auto_created = FALSE;
  }
  $form['title'] = array(
    '#type' => 'value',
    '#value' => $node->title,
  );
  if (!$node_auto_created) {
    $form['filename'] = array(
      '#type' => 'select',
      '#title' => t('select a text type'),
      '#required' => TRUE,
      '#options' => $apachesolr_multilingual_filetypes,
      '#default_value' => $node->filename,
    );
  }
  else {
    $form['filename'] = array(
      '#type' => 'value',
      '#value' => $node->filename,
    );
  }
  if ($node_auto_created) {
    if (file_exists($schema_source_path . $node->filename)) {
      $form[$node->filename] = array(
        '#type' => 'fieldset',
        '#title' => t('original apachesolr %filename example file', array(
          '%filename' => $node->filename,
        )),
        '#collapsible' => TRUE,
        '#collapsed' => TRUE,
      );
      $form[$node->filename][$node->filename . '_info'] = array(
        '#type' => 'item',
        '#title' => '',
        '#value' => nl2br(file_get_contents($schema_source_path . $node->filename)),
      );
    }
  }
  else {
    foreach ($apachesolr_multilingual_filetypes as $file) {
      if (file_exists($schema_source_path . $file)) {
        $form[$file] = array(
          '#type' => 'fieldset',
          '#title' => t('original apachesolr %file example file', array(
            '%file' => $file,
          )),
          '#collapsible' => TRUE,
          '#collapsed' => TRUE,
        );
        $form[$file][$file . '_info'] = array(
          '#type' => 'item',
          '#title' => '',
          '#value' => nl2br(file_get_contents($schema_source_path . $file)),
        );
      }
    }
  }
  if ($node->title) {
    $title = $node->title;
  }
  else {
    $title = 'Apache solr textfile';
  }
  $form['body'] = array(
    '#type' => 'textarea',
    '#title' => $title,
    '#rows' => 20,
    '#required' => FALSE,
    '#default_value' => $node->body,
    '#element_validate' => array(
      'apachesolr_multilingual_textfile_form_validate_new_config',
    ),
  );
  return $form;
}
function apachesolr_multilingual_textfile_form_validate_new_config($element, $form_state) {
  module_load_include('admin.inc', 'apachesolr_multilingual');
  apachesolr_multilingual_admin_form_validate_new_config($element, $form_state);
}
function apachesolr_multilingual_textfile_download_unique_langauge_config_validate($form, &$form_state) {
  apachesolr_multilingual_textfile_download_config_validate($form, $form_state, FALSE);
}
function apachesolr_multilingual_textfile_download_multilingual_config_validate($form, &$form_state) {
  apachesolr_multilingual_textfile_download_config_validate($form, $form_state, TRUE);
}
function apachesolr_multilingual_textfile_download_config_validate($form, &$form_state, $multilingual) {
  $selected_languages = variable_get('apachesolr_multilingual_languages', array());
  $apachesolr_multilingual_filetypes = variable_get('apachesolr_multilingual_filetypes', array(
    'stopwords.txt' => 'stopwords.txt',
    'synonyms.txt' => 'synonyms.txt',
    'protwords.txt' => 'protwords.txt',
    'compoundwords.txt' => 'compoundwords.txt',
  ));
  $language_count = 0;
  foreach ($selected_languages as $lang) {
    if ($lang) {
      $language_count++;
    }
  }
  if ($language_count) {

    // array for zip content
    $files = array();

    // languages to handle
    foreach ($selected_languages as $language) {
      if ($language) {
        foreach ($apachesolr_multilingual_filetypes as $filename) {
          $files[$filename] = '';
          if ($vid = db_result(db_query("SELECT vid FROM {apachesolr_multilingual_textfiles} JOIN {node} USING (vid) WHERE language = '%s' and filename = '%s'", $language, $filename))) {
            if ($node = node_load(array(
              'vid' => $vid,
            ))) {
              if ($multilingual) {
                $s2f = explode('.', $filename);
                $language_filename = $s2f[0] . '_' . $language . '.' . $s2f[1];
                $files[$language_filename] = apachesolr_multilingual_textfile_isolatin1accent_filter($node->body);
                if ('stopwords.txt' == $filename) {
                  $files['stopwords_spell_' . $language . '.txt'] = $node->body;
                }
              }
              else {
                $files[$filename] = apachesolr_multilingual_textfile_isolatin1accent_filter($node->body);
                if ('stopwords.txt' == $filename) {
                  $files['stopwords_spell.txt'] = $node->body;
                }
              }
            }
          }
        }
      }
    }
    require_once dirname(__FILE__) . '/../lib/apachesolr_multilingual_zipfile.php';
    $apachesolr_multilingual_config_zip = new apachesolr_multilingual_zipfile();
    $data = $form['solrconfig_str_complete']['#value'];
    $apachesolr_multilingual_config_zip
      ->addFile($data, 'solrconfig.xml');
    $data = $form['schema_str_complete']['#value'];
    $apachesolr_multilingual_config_zip
      ->addFile($data, 'schema.xml');
    $data = file_get_contents(dirname(__FILE__) . '/../resources/mapping-ISOLatin1Accent.txt');
    $apachesolr_multilingual_config_zip
      ->addFile($data, 'mapping-ISOLatin1Accent.txt');
    if (!isset($files['compoundwords.txt'])) {

      // solr example installation doesn't contain compoundwords.txt. so we have to ensure that it exists in our package
      $files['compoundwords.txt'] = '';
    }
    foreach ($files as $filename => $data) {
      if (strpos($filename, 'compoundwords') !== FALSE || strpos($filename, 'protwords') !== FALSE) {

        // compoundwords and protwords are used AFTER a lower case filter in schema.xml.
        // because isolatin1accent_filter converted all accent characters we don't need to care about the locale for strtolower
        $data = drupal_strtolower($data);
      }
      $apachesolr_multilingual_config_zip
        ->addFile($data, $filename);
    }
    drupal_set_header('Content-Type: application/x-gzip');
    drupal_set_header('Expires: ' . gmdate('D, d M Y H:i:s') . ' GMT');
    $file_name = $multilingual ? 'apachesolr_multilingual_config.zip' : 'apachesolr_unique_language_config.zip';
    drupal_set_header('Content-Disposition: inline; filename="' . $file_name . '"');
    drupal_set_header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    drupal_set_header('Pragma: public');
    print $apachesolr_multilingual_config_zip
      ->file();
    exit;
  }
  drupal_not_found();
}
function apachesolr_multilingual_textfile_form_alter(&$form, &$form_state, $form_id) {
  if ($form_id == 'apachesolr_multilingual_textfile_node_form') {
    if ($form['#node']->filename && $form['#node']->language) {
      unset($form['language']);
      $form['language']['#type'] = 'value';
      $form['language']['#value'] = $form['#node']->language;
    }
  }
  elseif ($form_id == 'node_type_form') {
    if ('apachesolr_multilingual_textfile' == $form['#node_type']->orig_type) {

      // set the needed values
      $form['workflow']['language_content_type']['#type'] = 'value';
      $form['workflow']['language_content_type']['#default_value'] = '1';

      // inform the user
      $form['workflow']['language_content_type_info']['#type'] = 'radio';
      $form['workflow']['language_content_type_info']['#values'] = array(
        0 => '0',
        1 => '1',
      );
      $form['workflow']['language_content_type_info']['#checked'] = 'checked';
      $form['workflow']['language_content_type_info']["#title"] = t("Multilingual support");
      $form['workflow']['language_content_type_info']["#description"] = t("Enabled multilingual support is necessary for this content type");
    }
  }
  elseif ($form_id == 'apachesolr_multilingual_admin_form') {
    $form['#submit'][] = 'apachesolr_multilingual_textfile_admin_form_submit';
  }
  elseif ($form_id == 'apachesolr_multilingual_schema_generator_form') {
    $apachesolr_multilingual_filetypes = variable_get('apachesolr_multilingual_filetypes', array(
      'stopwords.txt' => 'stopwords.txt',
      'synonyms.txt' => 'synonyms.txt',
      'protwords.txt' => 'protwords.txt',
      'compoundwords.txt' => 'compoundwords.txt',
    ));
    $selected_languages = variable_get('apachesolr_multilingual_languages', array());
    $language_count = 0;
    foreach ($selected_languages as $lang) {
      if ($lang) {
        $language_count++;
      }
    }
    if ($language_count > 0) {
      $form['#validate'][] = 'apachesolr_multilingual_textfile_form_validate';
      if ($language_count == 1) {
        $form['set1']['submit_zip'] = array(
          '#type' => 'submit',
          '#value' => t('Download !file', array(
            '!file' => 'apachesolr_unique_language_config.zip',
          )),
          '#validate' => array_merge($form['set1']['submit']['#validate'], array(
            'apachesolr_multilingual_textfile_download_unique_langauge_config_validate',
          )),
        );
      }
      $form['set2']['submit_zip'] = array(
        '#type' => 'submit',
        '#value' => t('Download !file', array(
          '!file' => 'apachesolr_multilingual_config.zip',
        )),
        '#validate' => array_merge($form['set2']['submit']['#validate'], array(
          'apachesolr_multilingual_textfile_download_multilingual_config_validate',
        )),
      );
      $form['set3'] = array(
        '#type' => 'fieldset',
        '#title' => t('Manage Multilingual Configuration Files'),
        '#weight' => 7,
        '#collapsible' => FALSE,
        '#collapsed' => FALSE,
      );
      $form['set3']['textfiles'] = array(
        '#type' => 'item',
        '#value' => theme('apachesolr_multilingual_textfile_form_element', $selected_languages),
      );
    }
  }
}
function apachesolr_multilingual_textfile_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
  if ('apachesolr_multilingual_textfile' == $node->type) {
    switch ($op) {
      case 'load':
        $node->filename = db_result(db_query("SELECT filename FROM {apachesolr_multilingual_textfiles} WHERE (nid = %d) and (vid = %d)", $node->nid, $node->vid));
        break;
      case 'presave':

        // prohibit publishing
        $node->status = 0;

        // create fix title
        $active_languages = locale_language_list();
        $node->title = $active_languages[$node->language] . ' / ' . $node->filename;
        break;
      case 'insert':
        $item = array(
          'nid' => $node->nid,
          'vid' => $node->vid,
          'filename' => $node->filename,
        );
        drupal_write_record('apachesolr_multilingual_textfiles', $item);
        break;
      case 'delete':

        // delete complete node therefore no revision control
        db_query("DELETE FROM {apachesolr_multilingual_textfiles} WHERE nid = %d", $node->nid);
        break;
      case 'update':
        $item = array(
          'nid' => $node->nid,
          'vid' => $node->vid,
          'filename' => $node->filename,
        );
        if ($node->revision) {
          drupal_write_record('apachesolr_multilingual_textfiles', $item);
        }
        else {
          drupal_write_record('apachesolr_multilingual_textfiles', $item, array(
            'nid',
            'vid',
          ));
        }
        break;
      case 'validate':
        if (!$node->language) {
          form_set_error('language', t('choose a language'));
          return;
        }
        if (!$node->filename) {
          form_set_error('filename', t('choose a filename'));
          return;
        }
        $nid = db_result(db_query("SELECT nid FROM {apachesolr_multilingual_textfiles} JOIN {node} USING (nid) WHERE language='%s' AND filename='%s'", $node->language, $node->filename));
        if ($nid && $nid != $node->nid) {
          $active_languages = locale_language_list();
          $title = $active_languages[$node->language] . ' / ' . $node->filename;
          form_set_error('title', t('node already exists: %title', array(
            '%title' => $title,
          )));
        }
        $error = apachesolr_multilingual_validate_solr_textfile($node->filename, $node->body);
        if ($error) {
          form_set_error('body', t('syntax error in apache solr textfile: %filename - %error', array(
            '%filename' => $node->filename,
            '%error' => $error,
          )));
        }
        break;
    }
  }
}
function apachesolr_multilingual_textfile_isolatin1accent_filter($text) {
  static $lines = array();
  if (empty($lines)) {
    $mapping_source_path = dirname(__FILE__) . '/../resources/';
    $mappings = file_get_contents($mapping_source_path . 'mapping-ISOLatin1Accent.txt');
    $mappings = preg_replace('/\\s*$/', '', $mappings);
    $mappings = preg_replace('/^\\s*/', '', $mappings);
    $lines = explode("\n", $mappings);
    foreach ($lines as $i => $line) {
      if (drupal_substr($line, 0, 1) == '#' || trim($line) == '') {
        unset($lines[$i]);
      }
    }
  }
  $sr = array(
    '"',
    ' ',
  );
  foreach ($lines as $line) {
    $line = str_replace($sr, '', $line);
    $mappings = explode("=>", $line);
    $text = preg_replace("@\\x{" . str_replace('\\u', '', $mappings[0]) . "}@u", $mappings[1], $text);
  }
  return $text;
}
function apachesolr_multilingual_validate_solr_textfile($filename, $text) {
  $message = '';

  // remove comments for checkup and split body in lines
  $text = preg_replace('/\\s*$/', '', $text);
  $text = preg_replace('/^\\s*/', '', $text);
  $lines = explode("\n", $text);
  foreach ($lines as $i => $line) {
    if (drupal_substr($line, 0, 1) == '#' || trim($line) == '') {
      unset($lines[$i]);
    }
  }

  // parser
  switch ($filename) {
    case 'stopwords.txt':
      foreach ($lines as $i => $line) {
        $words = explode(" ", $line);
        if (count($words) > 1) {
          $message = drupal_strtoupper('line ' . $i . ': (' . $line . ')');
          break;
        }
      }
      break;
    case 'synonyms.txt':
      foreach ($lines as $i => $line) {
        $words = explode(" ", $line);
        if (count($words) < 3) {
          $message = drupal_strtoupper('line ' . $i . ': (' . $line . ')');
          break;
        }
        if ($words[1] != '=>') {
          $message = drupal_strtoupper('line ' . $i . ': missing => (' . $line . ')');
          break;
        }
      }
      break;
    case 'protwords.txt':
      foreach ($lines as $i => $line) {
        $words = explode(" ", $line);
        if (count($words) > 1) {
          $message = drupal_strtoupper('line ' . $i . ': (' . $line . ')');
          break;
        }
      }
      break;
    case 'compoundwords.txt':
      break;
  }
  return $message;
}
function apachesolr_multilingual_textfile_admin_form_submit($form, &$form_state) {
  global $user;
  $active_languages = locale_language_list();
  $all_languages = language_list();
  $posted_languages = $form_state['values']['apachesolr_multilingual_languages'];
  $apachesolr_multilingual_filetypes = variable_get('apachesolr_multilingual_filetypes', array(
    'stopwords.txt' => 'stopwords.txt',
    'synonyms.txt' => 'synonyms.txt',
    'protwords.txt' => 'protwords.txt',
    'compoundwords.txt' => 'compoundwords.txt',
  ));

  // languages to handle
  if ($posted_languages) {
    foreach ($posted_languages as $language) {
      if ($language) {
        foreach ($apachesolr_multilingual_filetypes as $filename) {
          if ('protwords.txt' == $filename && !apachesolr_multilingual_get_stemmer($language)) {

            // solr contains no stemmer for this language. so we don't need protected words.
            continue;
          }
          if (!db_result(db_query("SELECT 1 FROM {apachesolr_multilingual_textfiles} JOIN {node} USING (nid) WHERE language='%s' AND filename='%s'", $language, $filename))) {

            // generate content
            $apachesolr_multilingual_textfile = new stdClass();
            $apachesolr_multilingual_textfile->type = 'apachesolr_multilingual_textfile';
            $apachesolr_multilingual_textfile->title = $active_languages[$language] . ' / ' . $filename;
            $apachesolr_multilingual_textfile->filename = $filename;
            $apachesolr_multilingual_textfile->status = 0;
            $apachesolr_multilingual_textfile->language = $language;
            $apachesolr_multilingual_textfile->uid = $user->uid;
            $apachesolr_multilingual_textfile->programmed = TRUE;
            node_save($apachesolr_multilingual_textfile);
            drupal_set_message(t('the content type named %filename has been created', array(
              '%filename' => $active_languages[$language] . ' / ' . $filename,
            )));
          }
          else {
            drupal_set_message(t('the content type named %filename already exists, nothing to do', array(
              '%filename' => $active_languages[$language] . ' / ' . $filename,
            )));
          }
        }
      }
    }
  }
}
function apachesolr_multilingual_textfile_perm() {
  return array(
    'view apachesolr_multilingual_textfile',
    'create apachesolr_multilingual_textfile',
    'edit apachesolr_multilingual_textfile',
    'delete apachesolr_multilingual_textfile',
  );
}
function apachesolr_multilingual_textfile_access($op, $node, $account) {
  switch ($op) {
    case 'view':
      return user_access('view apachesolr_multilingual_textfile', $account);
      break;
    case 'create':
      return user_access('create apachesolr_multilingual_textfile', $account);
      break;
    case 'update':
      return user_access('edit apachesolr_multilingual_textfile', $account);
      break;
    case 'delete':
      return user_access('delete apachesolr_multilingual_textfile', $account);
      break;
  }
  return FALSE;
}

/**
 * Displays the content type admin overview page.
 */
function theme_apachesolr_multilingual_textfile_form_element($selected_languages) {
  $header = array(
    t('Text File'),
    t('Size'),
    array(
      'data' => t('Operations'),
      'colspan' => 2,
    ),
  );
  $rows = array();
  foreach ($selected_languages as $language) {
    if ($language) {
      if ($result = db_query("SELECT * FROM {apachesolr_multilingual_textfiles} JOIN {node} USING (nid) WHERE language='%s'", $language)) {
        while ($db_rec = db_fetch_object($result)) {
          $bsize = db_result(db_query("SELECT length(body) FROM {node_revisions} WHERE nid='%d' and vid='%s'", $db_rec->nid, $db_rec->vid));
          if (!$bsize) {
            $bsize = '-';
          }
          $rows[] = array(
            array(
              'data' => $db_rec->title,
            ),
            array(
              'data' => $bsize,
            ),
            array(
              'data' => l(t('download'), 'node/' . $db_rec->nid . '/apachesolr_multilingual_textfile_download', array(
                'query' => array(
                  'destination' => 'admin/settings/apachesolr/schema_generator',
                ),
              )),
            ),
            array(
              'data' => l(t('edit'), 'node/' . $db_rec->nid . '/edit', array(
                'query' => array(
                  'destination' => 'admin/settings/apachesolr/schema_generator',
                ),
              )),
            ),
          );
        }
      }
    }
  }
  return theme('table', $header, $rows);
}
function apachesolr_multilingual_textfile_menu() {
  $items = array();
  $items['node/%node/apachesolr_multilingual_textfile_download'] = array(
    'title' => 'download apachesolr multilingual textfile',
    'page callback' => 'apachesolr_multilingual_textfile_download',
    'page arguments' => array(
      1,
    ),
    // REVIEW access rights
    'access callback' => 'node_access',
    'access arguments' => array(
      'view',
      1,
    ),
    'type' => MENU_CALLBACK,
  );
  return $items;
}
function apachesolr_multilingual_textfile_download($form) {
  if ($node = node_load(array(
    'vid' => $form->vid,
  ))) {
    $s2f = explode('.', $node->filename);
    $filename = $s2f[0] . '_' . $node->language . '.' . $s2f[1];
    $data = apachesolr_multilingual_textfile_isolatin1accent_filter($node->body);
    if (strpos($filename, 'compoundwords') !== FALSE || strpos($filename, 'protwords') !== FALSE) {

      // compoundwords and protwords are used AFTER a lower case filter in schema.xml.
      // because isolatin1accent_filter converted all accent characters we don't need to care about the locale for strtolower
      $data = drupal_strtolower($data);
    }
    drupal_set_header('Content-Type: text/xml; charset=utf-8');
    drupal_set_header("Content-Disposition: attachment; filename=\"{$filename}\"");
    print $data;
    exit;
  }
  drupal_not_found();
}