|
@@ -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";
|
|
|
+}
|