ソースを参照

Implement actual catalogue generation

Yves Chedemois 15 年 前
コミット
b625993082
4 ファイル変更357 行追加34 行削除
  1. BIN
      catalogue_template.odt
  2. 8 34
      fgcf.module
  3. 349 0
      fgcf.odt.inc
  4. BIN
      tutoriel3.odt

BIN
catalogue_template.odt


+ 8 - 34
fgcf.module

@@ -97,10 +97,9 @@ function fgcf_term_path($term) {
       return 'fgcf/format/'. $term->tid;
       break;
 
-    // @todo Quid de :
-    // - FGCF Supports remis (affiché en lien)
-    // - FGCF Sanction (affiché en lien)
-    // - FGCF Public visé (affiché en lien)
+    default:
+      // Terms in other vocabs should be set to display 'as text' (no link)
+      break;
   }
 }
 
@@ -296,38 +295,13 @@ function fgcf_page_thematique($thematique = 0) {
  * Page callback : 'ODT test'.
  */
 function fgcf_page_odt() {
-  $odf = fgcf_new_odt(dirname(__FILE__) ."/odtphp/tests/tutoriel1.odt");
-  $odf->setVars('titre', 'PHP');
-  $message = "PHP est un langage de scripts libre ... hello";
-  $odf->setVars('message', $message);
-  //$odf->saveToDisk('foo.odt');
-  $odf->exportAsAttachedFile();
-}
-
-function fgcf_new_odt($filename) {
-  fgcf_load_odt();
-  $options = array(
-    'PATH_TO_TMP' => file_directory_temp() .'/',
-    // The PHP Zip extension in recent PHP versions produces corrupt ODT
-    // archives. See http://www.odtphp.com/forum/viewtopic.php?f=4&t=43#p154.
-    'ZIP_PROXY' => 'PclZipProxy',
-  );
-  return new odf($filename, $options);
-}
-
-function fgcf_load_odt() {
-  // Use correct temp folders - see http://www.odtphp.com/forum/viewtopic.php?f=5&t=20#p126
+  module_load_include('inc', 'fgcf', 'fgcf.odt');
 
-  // Temp folder used by PclZipProxy - see the beginning of PclZipProxy.php.
-  // This folder is deleted and recreated each time, so we use a subfolder of
-  // the tmp dir.
-  define('PCL_ZIP_TMP', file_directory_temp() .'/phpodt/');
-  // Temp folder used by the pclzip library - see the beginning of
-  // pclzip.lib.php.
-  define('PCLZIP_TEMPORARY_DIR', file_directory_temp() .'/');
+  // @todo : à paramétrer
+  $template = dirname(__FILE__) ."/catalogue_template.odt";
+  $odf = fgcf_odt_export_formations($template);
 
-  // Load the OdtPHP library.
-  require_once(dirname(__FILE__) .'/odtphp/library/odf.php');
+  $odf->exportAsAttachedFile('catalogue.odt');
 }
 
 /**

+ 349 - 0
fgcf.odt.inc

@@ -0,0 +1,349 @@
+<?php
+
+/**
+ * Load the OdtPHP library and initialize some variables.
+ */
+function fgcf_load_odt() {
+  // Use correct temp folders - see http://www.odtphp.com/forum/viewtopic.php?f=5&t=20#p126
+
+  // Temp folder used by PclZipProxy - see the beginning of PclZipProxy.php.
+  // This folder is deleted and recreated each time, so we use a subfolder of
+  // the tmp dir.
+  define('PCL_ZIP_TMP', file_directory_temp() .'/phpodt/');
+  // Temp folder used by the pclzip library - see the beginning of
+  // pclzip.lib.php.
+  define('PCLZIP_TEMPORARY_DIR', file_directory_temp() .'/');
+
+  // Load the OdtPHP library.
+  require_once(dirname(__FILE__) .'/odtphp/library/odf.php');
+}
+
+/**
+ * Create a new odf object.
+ *
+ * @param $filename
+ *   The initial odt template (path relative to drupal root).
+ *
+ * @return odf
+ *   An odf object.
+ */
+function fgcf_new_odf($filename) {
+  fgcf_load_odt();
+  $options = array(
+    'PATH_TO_TMP' => file_directory_temp() .'/',
+    // The PHP Zip extension in recent PHP versions produces corrupt ODT
+    // archives. See http://www.odtphp.com/forum/viewtopic.php?f=4&t=43#p154.
+    'ZIP_PROXY' => 'PclZipProxy',
+  );
+  return new odf($filename, $options);
+}
+
+function fgcf_odt_export_formations($filename) {
+  // Create new odf object from the template.
+  $odf = fgcf_new_odf($filename);
+
+  $thematique_1_boucle = $odf->setSegment('thematique_1_boucle');
+
+  // Iterate over top-level terms in 'Thematique' vocab.
+  $vid = _fgcf_get_vocabulary_by_name('FGCF Thématique');
+  $tree = taxonomy_get_tree($vid);
+  foreach ($tree as $term) {
+    if ($term->depth == 0) {
+      // Insert replacements for the top-level term.
+      fgcf_odt_replace_term_1st_level($thematique_1_boucle, $term);
+
+      // Iterate over secondary terms.
+      $sub_tree = taxonomy_get_tree($vid, $term->tid);
+      foreach ($sub_tree as $term_2) {
+        // Select nodes for that term.
+        $result = taxonomy_select_nodes(array($term_2->tid), 'or', 0, FALSE, 'n.nid ASC');
+        while ($row = db_fetch_array($result)) {
+          // Insert replacements for the node in the nested 'formations_boucle'
+          // loop.
+          $formation_boucle = $thematique_1_boucle->formations_boucle;
+          $node = node_load($row['nid']);
+          fgcf_odt_replace_node_formation($formation_boucle, $node);
+          $formation_boucle->merge();
+        }
+      }
+
+      $thematique_1_boucle->merge();
+    }
+  }
+
+  $odf->mergeSegment($thematique_1_boucle);
+
+  return $odf;
+}
+
+function fgcf_odt_replace_term_1st_level($segment, $term) {
+  $replace = array();
+
+  $replace['thematique_1_nom'] = strip_tags(filter_xss_admin($term->description));
+  $replace['thematique_1_code'] = $term->name;
+
+  _fgcf_odt_replace_segment($segment, $replace);
+
+  // Additionally, insert image.
+  $term_nodes = nat_get_nids(array($term->tid), TRUE);
+  if ($term_node = current($term_nodes)) {
+    $file = $term_node->field_fgcf_thematique_logo[0]['filepath'];
+    $segment->setImage('thematique_1_image', $file);
+  }
+}
+
+function fgcf_odt_replace_node_formation($segment, $node) {
+  $keys = array(
+    'formation_drupal_id',
+    'formation_titre',
+    'formation_reference',
+    'formation_objectif',
+    'formation_contenu',
+    'formation_organisme',
+    'formation_modalites',
+    'formation_dif',
+    'formation_heures',
+    'formation_longueur',
+    'formation_format',
+    'formation_support',
+    'formation_sanction',
+    'formation_public',
+    'formation_thematique',
+  );
+  // Initialise replacements with 'unspecified' text.
+  $replace = array_fill_keys($keys, '-');
+
+  // formation_drupal_id
+  $replace['formation_drupal_id'] = $node->nid;
+
+  // formation_titre
+  $replace['formation_titre'] = $node->title;
+
+  // formation_reference
+  if (!empty($node->field_fgcf_fiche_reference[0]['value'])) {
+    $replace['formation_reference'] = $node->field_fgcf_fiche_reference[0]['value'];
+  }
+
+  // formation_objectif
+  if (!empty($node->field_fgcf_fiche_objectif[0]['value'])) {
+    $replace['formation_objectif'] = check_markup($node->field_fgcf_fiche_objectif[0]['value'], $node->field_fgcf_fiche_objectif[0]['format']);
+  }
+
+  // formation_contenu
+  // @todo bug sur certains nodes 220
+  if (!empty($node->field_fgcf_fiche_contenu[0]['value'])) {
+    // Do not translate markdown syntax - only replace bullet points
+    $replace['formation_contenu'] = $node->field_fgcf_fiche_contenu[0]['value'];
+    //$replace['formation_contenu'] = check_markup($node->field_fgcf_fiche_contenu[0]['value'], $node->field_fgcf_fiche_contenu[0]['format']);
+  }
+
+  // formation_organisme
+  // @todo : organisme peut être multiple
+  // @todo bug sur nodes 220 221 : Staff & Line Management
+  $node_organisme = node_load($node->field_fgcf_fiche_organisme[0]['nid']);
+  $replace['formation_organisme'] = $node_organisme->title;
+
+  // formation_modalites
+  $field = content_fields('field_fgcf_fiche_modalite', 'fgcf_fiche');
+  $map = content_allowed_values($field);
+  $values = array();
+  foreach ((array) $node->field_fgcf_fiche_modalite as $item) {
+    if (isset($map[$item['value']])) {
+      $values[] = $map[$item['value']];
+    }
+  }
+  if ($values) {
+    $replace['formation_modalites'] = implode(', ', $values);
+  }
+
+  // formation_dif
+  if (!empty($node->field_fgcf_fiche_dif[0]['value'])) {
+    $item = $node->field_fgcf_fiche_dif['0']['value'];
+    $field = content_fields('field_fgcf_fiche_dif', 'fgcf_fiche');
+    $map = content_allowed_values($field);
+    if (isset($map[$item])) {
+      $replace['formation_dif'] = $map[$item];
+    }
+  }
+
+  // formation_heures
+  if (isset($node->field_fgcf_fiche_heures[0]['value'])) {
+    $value = $node->field_fgcf_fiche_heures[0]['value'];
+    $replace['formation_heures'] = format_plural($value, '@count heure', '@count heures');
+  }
+
+  // formation_longeur
+  if (isset($node->field_fgcf_fiche_jours[0]['value'])) {
+    $value = $node->field_fgcf_fiche_jours[0]['value'];
+    $replace['formation_longueur'] = format_plural($value, '@count jour', '@count jours');
+  }
+
+  // formation_format
+  $values = array();
+  foreach ((array) $node->field_fgcf_fiche_format as $item) {
+    $tid = $item['value'];
+    if ($term = taxonomy_get_term($tid)) {
+      $values[] = $term->name;
+    }
+  }
+  if ($values) {
+    // @todo : liste en items ?
+    $replace['formation_format'] = implode(', ', $values);
+  }
+
+  // formation_support
+  $values = array();
+  foreach ((array) $node->field_fgcf_fiche_supports as $item) {
+    $tid = $item['value'];
+    if ($term = taxonomy_get_term($tid)) {
+      $values[] = $term->name;
+    }
+  }
+  if ($values) {
+    // @todo : liste en items ?
+    $replace['formation_support'] = implode(', ', $values);
+  }
+
+  // formation_sanction
+  $values = array();
+  foreach ((array) $node->field_fgcf_fiche_sanction as $item) {
+    $tid = $item['value'];
+    if ($term = taxonomy_get_term($tid)) {
+      $values[] = $term->name;
+    }
+  }
+  if ($values) {
+    // @todo : liste en items ?
+    $replace['formation_sanction'] = implode(', ', $values);
+  }
+
+  // formation_public
+  $values = array();
+  foreach ((array) $node->field_fgcf_fiche_public as $item) {
+    $tid = $item['value'];
+    if ($term = taxonomy_get_term($tid)) {
+      $values[] = $term->name;
+    }
+  }
+  if ($values) {
+    // @todo : liste en items ?
+    $replace['formation_public'] = implode(', ', $values);
+  }
+
+  // formation_thematique
+  $values = array();
+  foreach ((array) $node->taxonomy as $term) {
+    if ($term->vid == _fgcf_get_vocabulary_by_name('FGCF Thématique')) {
+      $parents = taxonomy_get_parents($term->tid);
+      if ($parents) {
+        $parent = current($parents);
+        $values[] = strip_tags(filter_xss_admin($parent->description));
+      }
+
+      $values[] = strip_tags(filter_xss_admin($term->description));
+      break;
+    }
+  }
+  if ($values) {
+    // @todo mise en forme ?
+    $replace['formation_thematique'] = implode(' / ', $values);
+  }
+
+  _fgcf_odt_replace_segment($segment, $replace);
+}
+
+function _fgcf_odt_replace_segment($segment, $replace) {
+  foreach ($replace as $key => $value) {
+    try {
+      $segment->setVars($key, $value, FALSE, 'UTF-8');
+    }
+    catch (SegmentException $e) {
+      // Pattern was not found in the template.
+    }
+  }
+}
+
+/**
+ * Stolen and adapted from markdown.php :
+ * Form HTML ordered (numbered) and unordered (bulleted) lists.
+ */
+function doLists($text) {
+  $less_than_tab = $this->tab_width - 1;
+
+  # Re-usable patterns to match list item bullets and number markers:
+  $marker_ul_re  = '[*+-]';
+  $marker_ol_re  = '\d+[.]';
+  $marker_any_re = "(?:$marker_ul_re|$marker_ol_re)";
+
+  $markers_relist = array(
+    $marker_ul_re => $marker_ol_re,
+    $marker_ol_re => $marker_ul_re,
+  );
+
+  foreach ($markers_relist as $marker_re => $other_marker_re) {
+    # Re-usable pattern to match any entirel ul or ol list:
+    $whole_list_re = '
+      (               # $1 = whole list
+        (               # $2
+        ([ ]{0,'.$less_than_tab.'}) # $3 = number of spaces
+        ('.$marker_re.')      # $4 = first list item marker
+        [ ]+
+        )
+        (?s:.+?)
+        (               # $5
+          \z
+        |
+          \n{2,}
+          (?=\S)
+          (?!           # Negative lookahead for another list item marker
+          [ ]*
+          '.$marker_re.'[ ]+
+          )
+        |
+          (?=           # Lookahead for another kind of list
+            \n
+          \3            # Must have the same indentation
+          '.$other_marker_re.'[ ]+
+          )
+        )
+      )
+    '; // mx
+
+    # We use a different prefix before nested lists than top-level lists.
+    # See extended comment in _ProcessListItems().
+
+    if ($this->list_level) {
+      $text = preg_replace_callback('{
+          ^
+          '.$whole_list_re.'
+        }mx',
+        array(&$this, '_doLists_callback'), $text);
+    }
+    else {
+      $text = preg_replace_callback('{
+          (?:(?<=\n)\n|\A\n?) # Must eat the newline
+          '.$whole_list_re.'
+        }mx',
+        array(&$this, '_doLists_callback'), $text);
+    }
+  }
+
+  return $text;
+}
+function _doLists_callback($matches) {
+  # Re-usable patterns to match list item bullets and number markers:
+  $marker_ul_re  = '[*+-]';
+  $marker_ol_re  = '\d+[.]';
+  $marker_any_re = "(?:$marker_ul_re|$marker_ol_re)";
+
+  $list = $matches[1];
+  $list_type = preg_match("/$marker_ul_re/", $matches[4]) ? "ul" : "ol";
+
+  $marker_any_re = ( $list_type == "ul" ? $marker_ul_re : $marker_ol_re );
+
+  $list .= "\n";
+  $result = $this->processListItems($list, $marker_any_re);
+
+  $result = $this->hashBlock("<$list_type>\n" . $result . "</$list_type>");
+  return "\n". $result ."\n\n";
+}

BIN
tutoriel3.odt