<?php
// $Id: l10n_packager.module,v 1.1.2.3 2009/11/11 18:21:01 goba Exp $

/**
 * @file
 *   Localization packager module for localization server.
 */

/**
 * Release packager status: do not repackage anymore.
 */
define('L10N_PACKAGER_DISABLED', 0);

/**
 * Release packager status: keep repackaging.
 */
define('L10N_PACKAGER_ACTIVE', 1);

/**
 * Release packager status: error.
 */
define('L10N_PACKAGER_ERROR', 2);

/**
 * Default path structure for generated files
 */
define('L10N_PACKAGER_FILEPATH', '%core/%project/%project-%release.%language.po');

/**
 * Implementation of hook_menu().
 */
function l10n_packager_menu() {
  $items['admin/l10n_server/packager'] = array(
    'title' => 'Packaging tools',
    'description' => 'Select project, releases and languages to repackage.',
    'page callback' => 'l10n_packager_admin_repackage_page',
    'file' => 'l10n_packager.admin.inc',
    'access arguments' => array('administer localization community'),
  );
  $items['admin/l10n_server/packager/package'] = array(
    'title' => 'Package',
    'type' => MENU_DEFAULT_LOCAL_TASK,
    'weight' => -10,
  );
  $items['admin/l10n_server/packager/configure'] = array(
    'title' => 'Configure',
    'description' => 'Configure automatic packaging for translations.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('l10n_packager_settings_form'),
    'file' => 'l10n_packager.admin.inc',
    'access arguments' => array('administer localization community'),
    'type' => MENU_LOCAL_TASK,
    'weight' => 10,
  );
  return $items;
}

/**
 * Implementation of hook_cron().
 */
function l10n_packager_cron() {
  if (variable_get('l10n_packager_cron', 0) && ($interval = variable_get('l10n_packager_update', 0))) {
    module_load_include('inc', 'l10n_packager');
    $timestamp = time() - $interval;
    $file_limit = variable_get('l10n_packager_file_limit', 1);
    $count_files = $count_check = 0;

    // Go for it: check releases for repackaging. We need project_uri for later
    $result = db_query_range("SELECT r.rid, r.pid, r.title, pr.checked, pr.updated, pr.status, p.uri FROM {l10n_community_release} r INNER JOIN {l10n_community_project} p ON r.pid = p.pid LEFT JOIN {l10n_packager_release} pr ON pr.rid = r.rid WHERE pr.status IS NULL OR (pr.status = %d AND (pr.checked < %d OR pr.updated < %d)) ORDER BY pr.checked", L10N_PACKAGER_ACTIVE, $timestamp, $timestamp, 0, variable_get('l10n_packager_release_limit', 10));

    while ((!$file_limit || $file_limit > $count_files) && ($release = db_fetch_object($result))) {
      $updates = l10n_packager_release_check($release, FALSE, $file_limit - $count_files, NULL, TRUE);
      $count_files += count($updates);
      $count_check++;
    }
    watchdog('l10n_packager', 'Checked %checked releases. Repackaged %repack translations.', array('%checked' => $count_check, '%repack' => $count_files));
  }
}

// == Language list export =====================================================

/**
 * Implementation of hook_form_alter().
 */
function l10n_packager_form_alter(&$form, $form_state, $form_id) {
  $languages_forms = array(
    'locale_languages_configure_form',
    'locale_languages_edit_form',
    'locale_languages_delete_form',
    'locale_languages_predefined_form',
    'locale_languages_custom_form',
  );
  if (in_array($form_id, $languages_forms)) {
    $form['#submit'][] = 'l10n_packager_export_language_list';
  }
}

/**
 * Export languages in a simple XML format for remote use.
 */
function l10n_packager_export_language_list() {
  $languages = language_list('language', TRUE);
  $xml = simplexml_load_string("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<languages></languages>");

  foreach ($languages as $language) {
    $item = $xml->addChild("language");
    foreach (array('name', 'native', 'language') as $key) {
      $item->addChild($key, $language->$key);
    }
  }
  $xml_path = l10n_packager_directory();
  file_check_directory($xml_path, FILE_CREATE_DIRECTORY);
  if ($xml->asXML($xml_path .'/languages.xml')) {
    drupal_set_message(t('Languages XML exported.'));
  }
  else {
    drupal_set_message(t('Error when try export languages XML'), 'error');
  }
}

// == Utility functions ========================================================

/**
 * Get directory for creating files
 */
function l10n_packager_directory() {
  return variable_get('l10n_packager_directory', file_directory_path() .'/l10n_packager');
}

/**
 * Ensure that directories on the $path exist in our packager directory.
 */
function l10n_packager_create_path($path) {
  $directory = dirname($path);
  $basepath = $currentpath = l10n_packager_directory();
  $finalpath = $basepath .'/'. $directory;
  $parts = explode('/', $directory);
  while (is_dir($currentpath) && !is_dir($finalpath) && ($more = array_shift($parts))) {
    $currentpath .= '/'. $more;
    file_check_directory($currentpath, FILE_CREATE_DIRECTORY);
  }
  return $basepath .'/'. $path;
}

/**
 * Build target filepath from release object based on the set pattern.
 */
function l10n_packager_get_filepath($release, $language) {
   // Release name should be like 6.x-1.2-beta1 for contrib modules
   // and 6.11 for core (where $core is actually $version).
   @list($core, $version, $extra) = explode('-', $release->title);
   if (empty($version)) {
     $version = $core;
     list($major, $minor) = explode('.', $core);
     $core = $major .'-x';
   }
   $replace = array(
    '%project'  => $release->uri,
    '%release'  => $release->title,
    '%core'     => $core,
    '%version'  => $version,
    '%extra'    => !empty($extra) ? '-'. $extra : '',
    '%language' => $language->language,
   );
   return strtr(variable_get('l10n_packager_filepath', L10N_PACKAGER_FILEPATH), $replace);
}
