source: sipes/0.3-modules/politicas_proyectos/politicas_proyectos.module @ eb502b4

stable
Last change on this file since eb502b4 was 616e50e, checked in by Sipes Apn <root@…>, 7 años ago

se comento el acceso al campo de ubicacion

  • Propiedad mode establecida a 100644
File size: 42.9 KB
Línea 
1<?php
2  /**
3  * Sistema Integral de Planificación y Presupuesto (SIPP)
4  * @file politicas_proyectos.module
5  * Drupal part Module to Sistema Integral de Planificación y Presupuesto (SIPP)
6  * Copyright 2017 Sistema Automatizado para la Planificación Estratégico-Situacional en la Administración Pública Venezolana (CENDITEL)
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21  *
22  * @author Cenditel Merida - Msc. Juan Vizcarrondo
23  * @date 2017-08-15 // (a&#241;o-mes-dia)
24  * @version 0.3 // (0.3)
25  *
26  */
27
28
29/*
30 * Implementation of hook_menu()
31 */
32function politicas_proyectos_menu() {
33  $items = array();
34  $items['politicas_proyectos_get_politicas_js'] = array(
35    'title' => 'Ente Planificador',
36    'page callback' => 'politicas_proyectos_get_politicas_js',
37    'access arguments' => array('ver planificador'),
38    'type' => MENU_CALLBACK,
39  );
40  return $items;
41}
42
43function politicas_proyectos_get_politicas_js($campo = '') {
44  $form_state = array('submitted' => FALSE);
45  $form_build_id = $_POST['form_build_id'];
46  $form = form_get_cache($form_build_id, $form_state);
47  $politica = array();
48  $arreglo = array();
49  if (isset($_POST[$form['#politicas_campo']]['nid']) && is_array($_POST[$form['#politicas_campo']]['nid'])) {
50    $arreglo = $_POST[$form['#politicas_campo']]['nid'];
51  }
52  elseif (isset($_POST[$form['#politicas_campo']]) && is_array($_POST[$form['#politicas_campo']])) {
53    $arreglo = $_POST[$form['#politicas_campo']];
54  }
55  foreach($arreglo as $valor) {
56    $valor = intval($valor);
57    if ($valor) {
58      $politica[$valor] = $valor;
59    }
60  }
61  $form['#causas'] = array();
62  $form['#cambios'] = array();
63  $form['#descriptores'] = array();
64  $form['#formas_solucion'] = array();
65  $form['#carabobo'] = array();
66  $form['#all_descriptores'] = array();
67  $form['#formas_solucion'] = array();
68  $form['#pdlp'] = array();
69  $form['#politica'] = $politica;
70  $output = t('No ha seleccionado una politica');
71  if ($politica) {
72    $busca_causas = array();
73    foreach($politica as $id) {
74      $busca_causas += $form['#causas_criticas'][$id];
75    }
76    $descriptores_c = _politicas_proyectos_get_causas_all_causas('criticas', $busca_causas);
77    $form['#formas_solucion'] = politicas_proyectos_get_formas_solucion($busca_causas);
78    $all_descriptores = _politicas_proyectos_situacion_actual_listar_all_descriptores($descriptores_c);
79    $form['#all_descriptores'] = $all_descriptores;
80    $form['#descriptores'] = $all_descriptores['descriptores'];
81    $form['#causas'] = $all_descriptores['causas'];
82    $form['#cambios'] = $all_descriptores['cambios'];
83    $form['#pdlp'] = $all_descriptores['pdlp'];
84    $form['#carabobo'] = $all_descriptores['carabobo'];
85    $output = _politicas_proyectos_display_politicas($form['#all_descriptores'], $form['#formas_solucion']);
86  }
87  //$form += $new_form;
88  form_set_cache($form_build_id, $form, $form_state);
89  $form += array(
90    '#post' => $_POST,
91    '#programmed' => FALSE,
92  );
93  // Rebuild the form.
94  $form = form_builder($_POST['form_id'], $form, $form_state);
95  // Add the new element to the stored form. Without adding the element to the
96  // form, Drupal is not aware of this new elements existence and will not
97  // process it. We retreive the cached form, add the element, and resave.
98  print drupal_to_js(array('data' => $output, 'status' => true));
99  exit();
100}
101
102
103/*
104 * Implementation of _politicas_proyectos_situacion_actual_listar_all_descriptores()
105 * Get ente's descriptores
106 * Inputs:
107   - $ente_planificador (integer): ente planificador nid
108   - $tipo (integer): plann type
109   - $year (integer): descriptor year creation, if no available 'situacional_actual_preliminar_anho_creacion' variable will be used
110 * Outputs:
111   - Descriptores (array nid descriptor):
112     + body: Description descriptor
113     + title: Acronimo
114     + nid: Descriptor nid node reference
115     + year: descriptor year creation
116     + clasificacion: descriptor type
117       / tid: taxonomy term
118     + causas: causas list (array nid causa-descriptor):
119       / body: Description causa
120       / title: Acronimo causa
121       / nid: Causa nid node reference
122       / descriptor: Descriptor nid node reference
123     + solucion: solucion list (array nid solucion-descriptor):
124       / body: Description solucion
125       / title: Acronimo solucion
126       / nid: Solucion nid node reference
127       / descriptor: Descriptor nid node reference
128 */
129function _politicas_proyectos_situacion_actual_listar_all_descriptores($causas = array()) {
130  //se obtienen los descriptores
131  $descriptores = array();
132  $causas_load = array();
133  $cambios_load = array();
134  $pdlp_load = array();
135  $carabobo_load = array();
136  $sql = "SELECT c.nid, n.title, nr.body FROM {content_type_descriptores} AS c INNER JOIN {node} AS n ON c.nid = n.nid AND c.vid = n.vid AND n.type = 'descriptores' INNER JOIN {node_revisions} AS nr  ON c.nid = nr.nid AND c.vid = nr.vid";
137  $inputs = array();
138  $inputs_c = array();
139  if (is_array($causas) && count($causas)) {
140    $implode_causas_sql = array();
141    foreach($causas as $id => $descriptoresl) {
142      $implode_causas_sql[] = '%d';
143      $inputs_c[] = $id;
144      foreach($descriptoresl as $descriptor) {
145        $implode_sql[] = '%d';
146        $inputs[] = $descriptor;
147      }
148    }
149    if (count($implode_sql)) {
150      $sql .= ' WHERE c.nid IN (' . implode(', ', $implode_sql) . ')';
151    }
152  }
153
154  $tipo_plan = 'situacion_actual';
155  $planns = _situacion_actual_preliminar_get_planns();
156  $plan = $planns[$tipo_plan];
157
158  $sql .=' AND c.field_descriptores_' . $plan['short'] . '_value = %d';
159  $inputs[] = 1;
160
161  $sql .=' ORDER BY c.nid';
162  $result = db_query($sql, $inputs);
163  $inpunts = array();
164  $inpunts_values = array();
165  $solucion = array();
166  while($descriptor = db_fetch_object($result)) {
167    $descriptores[$descriptor->nid] = array(
168      'body' => $descriptor->body,
169      'title' => $descriptor->title,
170      'nid' => $descriptor->nid,
171      'year' => $year_display,
172      'clasificacion' => array(),
173      'causas' => array(),
174      'cambios' => array(),
175    );
176    $inpunts[] = '%d';
177    $inpunts_values[] = $descriptor->nid;
178  }
179  if (count($inpunts)) {
180    $implode = implode(',', $inpunts);
181    //Se obtienen la clasificacion de los descriptores
182    $sql = 'SELECT c.field_descriptores_clasificacion_value AS tid, c.nid FROM {content_field_descriptores_clasificacion} AS c INNER JOIN {node} AS n ON n.nid = c.nid AND n.vid = c.vid WHERE c.nid IN (' . $implode . ')';
183    $result = db_query($sql, $inpunts_values);
184    while($clasificacion = db_fetch_object($result)) {
185      $descriptores[$clasificacion->nid]['clasificacion'][$clasificacion->tid] = $clasificacion->tid;
186    }
187    //se obtienen las causas
188    //field_descriptores_causa
189    $sql = "SELECT c.field_descriptores_causa_nid as nid, c.nid as descriptor, n.title, nr.body FROM {content_field_descriptores_causa} AS c INNER JOIN {node} AS n ON c.field_descriptores_causa_nid = n.nid AND n.type = 'causas' INNER JOIN {node} AS n1 ON c.nid = n1.nid AND c.vid = n1.vid INNER JOIN {node_revisions} AS nr ON n.nid = nr.nid AND n.vid = nr.vid WHERE c.nid IN (" . $implode . ")";
190    $inpunts_d = $inpunts_values;
191    if (count($implode_causas_sql)) {
192      $sql .= ' AND c.field_descriptores_causa_nid IN (' . implode(', ', $implode_causas_sql) . ')';
193      $inpunts_d = array_merge($inpunts_values, $inputs_c);
194    }
195    $sql .= ' ORDER BY c.field_descriptores_causa_nid';
196    $result = db_query($sql, $inpunts_d);
197    while($causa = db_fetch_object($result)) {
198      $causas_load[$causa->nid] = array(
199        'descriptor' => $causa->descriptor,
200        'body' => $causa->body,
201        'nid' => $causa->nid,
202      );
203      $descriptores[$causa->descriptor]['causas'][$causa->nid] = array(
204        'body' => $causa->body,
205        'nid' => $causa->nid,
206        'title' => $causa->title,
207        'descriptor' => $causa->descriptor,
208      );
209    }
210    //se obtienen los cambios
211    //field_descriptor_cambio_nid
212    $sql_implode_cambios = array();
213    $inputs_cambios = array();
214    $sql = "SELECT c.field_descriptor_cambio_nid as nid, c.nid as descriptor, n.title, nr.body FROM {content_field_descriptor_cambio} AS c INNER JOIN {node} AS n ON c.field_descriptor_cambio_nid = n.nid AND n.type = 'cambios' INNER JOIN {node} AS n1 ON c.nid = n1.nid AND c.vid = n1.vid INNER JOIN {node_revisions} AS nr ON n.nid = nr.nid AND n.vid = nr.vid WHERE c.nid IN (" . $implode . ") ORDER BY c.field_descriptor_cambio_nid";
215    $result = db_query($sql, $inpunts_values);
216    while($meta = db_fetch_object($result)) {
217      $cambios_load[$meta->nid] = array(
218        'descriptor' => $meta->descriptor,
219        'body' => $meta->body,
220        'nid' => $meta->nid,
221        'pdlp' => array(),
222        'carabobo' => array(),
223      );
224      $sql_implode_cambios[] = '%d';
225      $inputs_cambios[] = $meta->nid;
226      $descriptores[$meta->descriptor]['cambios'][$meta->nid] = array(
227        'body' => $meta->body,
228        'nid' => $meta->nid,
229        'title' => $meta->title,
230        'descriptor' => $meta->descriptor,
231        'pdlp' => array(),
232        'carabobo' => array(),
233      );
234    }
235    //se obtienen pdlp y carabobo
236    if (count($inputs_cambios)) {
237      $implode = implode(', ', $sql_implode_cambios);
238      $sql = "SELECT p.*, t.name, t.description FROM {content_field_cambios_pdp} AS p INNER JOIN {node} AS n ON n.nid = p.nid AND n.vid = p.vid AND n.type = 'cambios' INNER JOIN {term_data} AS t ON t.tid = p.field_cambios_pdp_value WHERE p.nid IN (" . $implode . ") ORDER BY t.name";
239
240      $result = db_query($sql, $inputs_cambios);
241      while($meta = db_fetch_object($result)) {
242        if ($meta->field_cambios_pdp_value) {
243          $descriptores[$cambios_load[$meta->nid]['descriptor']]['cambios'][$meta->nid]['pdlp'][$meta->delta][$meta->field_cambios_pdp_value] = $meta->name . ' ' . $meta->description;
244          $cambios_load[$meta->nid]['pdlp'][$meta->delta][$meta->field_cambios_pdp_value] = $meta->name . ' ' . $meta->description;
245          $pdlp_load[$meta->delta][$meta->field_cambios_pdp_value] = $meta->name . ' ' . $meta->description;
246        }
247      }
248      $sql = "SELECT p.*, t.plan_carabobo_meta_value AS carabobo FROM {content_field_cambios_carabobo} AS p INNER JOIN {node} AS n ON n.nid = p.nid AND n.vid = p.vid AND n.type = 'cambios' INNER JOIN {term_fields_term} AS t ON t.tid = p.field_cambios_carabobo_value WHERE p.nid IN (" . implode(', ', $inputs_cambios) . ")";
249      $result = db_query($sql, $inputs_cambios);
250      while($meta = db_fetch_object($result)) {
251        if ($meta->field_cambios_carabobo_value) {
252          $descriptores[$cambios_load[$meta->nid]['descriptor']]['cambios'][$meta->nid]['carabobo'][$meta->delta][$meta->field_cambios_carabobo_value] = $meta->carabobo;
253          $cambios_load[$meta->nid]['carabobo'][$meta->delta][$meta->field_cambios_carabobo_value] = $meta->carabobo;
254          $carabobo_load[$meta->field_cambios_carabobo_value] = $meta->carabobo;
255        }
256      }
257    }
258  }
259  return array(
260    'descriptores' => $descriptores,
261    'causas' => $causas_load,
262    'cambios' => $cambios_load,
263    'pdlp' => $pdlp_load,
264    'carabobo' => $carabobo_load,
265  );
266}
267
268/*
269 * hook_form_alter()
270 */
271function politicas_proyectos_form_alter(&$form, $form_state, $form_id) {
272  if ($form_id == 'proyectos_operativos_proyecto_genera_campos_form') {
273    if (!isset($_SESSION['proyectos_operativos_mostrar_campos'][$form['#node']->nid]) || !count($_SESSION['proyectos_operativos_mostrar_campos'][$form['#node']->nid])) {
274    $form['db']['areae']['#options']['field_proyectos_descript'] = t('Descriptores (Problemas)');
275    $form['db']['areae']['#options']['field_proyectos_cambios'] = t('Cambios en la situación Actual');
276    $form['db']['areae']['#options']['field_proyectos_causasc'] = t('Causas Críticas');
277    //se borra el campo consecuencias
278    unset($form['ip']['enunciadop']['#options']['field_proyecto_consecuencias']);
279    }
280  }
281  if ($form_id == 'proyectos_operativos_proyecto_basico_form') {
282    $new_submit = array();
283    //se coloca el submit de pd
284    $new_submit[] = '_politicas_proyectos_basico_form_pd_submit';
285    foreach($form['#submit'] as $submit) {
286      $new_submit[] = $submit;
287    }
288    $form['#submit'] = $new_submit;
289    //se agregan los nuevos campos
290    if (isset($form['field_proyecto_pndes'])) {
291      unset($form['field_proyecto_pndes']);
292    }
293//    $form['field_proyecto_pndes']['#access'] = FALSE;
294    $form['#proyectos_operativos_fields'][] = 'field_proyecto_problemas';
295    $form['#proyectos_operativos_fields'][] = 'field_proyectos_descript';
296    $form['#proyectos_operativos_fields'][] = 'field_proyecto_causas';
297    $form['#proyectos_operativos_fields'][] = 'field_proyectos_causasc';
298    $form['#proyectos_operativos_fields'][] = 'field_proyectos_cambios';
299    $form['#proyectos_operativos_fields'][] = 'field_proyectos_solucion';
300    $form['#proyectos_operativos_fields'][] = 'field_proyecto_pndes';
301    $form['#proyectos_operativos_fields'][] = 'field_proyectos_carabobo';
302    $politicas = _politicas_proyectos_references($form['#ente_planificador']->nid, 1);
303    $form['#politicas'] = $politicas;
304    $form['#causas'] = array();
305    $form['#cambios'] = array();
306    $form['#descriptores'] = array();
307    $form['#formas_solucion'] = array();
308    $form['#mpcc'] = array();
309    $form['#pdlp'] = array();
310    $causas_criticas = _politicas_proyectos_get_politicas_causas($form['#politicas']['politicas']);
311    $politicas = array();
312    //solo deje aquellas politicas que contengan causas criticas
313    foreach($form['#politicas']['politicas'] as $id => $pol) {
314      if (isset($causas_criticas[$id]) && is_array($causas_criticas[$id]) && count($causas_criticas[$id])) {
315        $politicas[$id] = $pol;
316      }
317    }
318    $form['#politicas']['politicas'] = $politicas;
319    $form['#causas_criticas'] = $causas_criticas;
320    $form['#carabobo'] = array();
321    $politica = array();
322    if (isset($form['#node']->field_proyecto_mcti) && is_array($form['#node']->field_proyecto_mcti)) {
323      foreach($form['#node']->field_proyecto_mcti as $valor) {
324        if ($valor['nid']) {
325          $politica[$valor['nid']] = $valor['nid'];
326        }
327      }
328    }
329    //no deje enviar el formulario si no existen politicas para este ente
330    $form['buttons']['registrar']['#access'] = is_array($form['#politicas']['politicas']) && count($form['#politicas']['politicas']);
331
332    if (!count($politica) && is_array($form['#politicas']['politicas']) && count($form['#politicas']['politicas'])) {
333      //se obtiene el primer elemento del arreglo
334      $key = key($form['#politicas']['politicas']);
335      $politica[$key] = $key;
336    }
337    $form['#politicas_campo'] = 'field_proyecto_mcti';
338    $form['#politica'] = $politica;
339    if (count($form['#politica'])) {
340      $busca_causas = array();
341      foreach($form['#politica'] as $id) {
342        if (isset($form['#causas_criticas'][$id]) && is_array($form['#causas_criticas'][$id]) && count($form['#causas_criticas'][$id])) {
343          foreach($form['#causas_criticas'][$id] as $causa) {
344            $busca_causas[$causa] = $causa;
345          }
346        }
347      }
348      $descriptores_c = _politicas_proyectos_get_causas_all_causas('criticas', $busca_causas);
349      $form['#formas_solucion'] = politicas_proyectos_get_formas_solucion($busca_causas);
350      $all_descriptores = _politicas_proyectos_situacion_actual_listar_all_descriptores($descriptores_c);
351      $form['#all_descriptores'] = $all_descriptores;
352      $form['#descriptores'] = $all_descriptores['descriptores'];
353      $form['#causas'] = $all_descriptores['causas'];
354      $form['#cambios'] = $all_descriptores['cambios'];
355      $form['#pdlp'] = $all_descriptores['pdlp'];
356      $form['#carabobo'] = $all_descriptores['carabobo'];
357    }
358  }
359  if ($form_id == 'proyectos_operativos_proyecto_indicadores_form') {
360    $arreglo = array(
361      'field_proyecto_causas' => 'field_proyecto_causas',
362      'field_proyecto_problemas' => 'field_proyecto_problemas',
363      'field_proyecto_consecuencias' => 'field_proyecto_consecuencias',
364    );
365    foreach($arreglo as $id) {
366      if (isset($form['field_proyecto_causas'])) {
367        unset($form[$id]);
368        $title = $form['#field_info'][$id]['widget']['label'];
369        unset($form['#field_info'][$id]);
370        $items = array();
371        if ($id != field_proyecto_consecuencias) {
372          foreach($form['#node']->{$id} as $valor) {
373            $items[] = $valor['value'];
374          }
375          $form[$id] = array(
376            '#value' => '<div id="edit-field-proyecto-' . $id . '-0-value-wrapper" class="form-item"><label for="edit-field-proyecto-' . $id . '-0-value">' . $title . '</label>' . theme('item_list', $items) . '</div>',
377          );
378        }
379      }
380    }
381    $new_fields = array();
382    foreach($form['#proyectos_operativos_fields'] as $id) {
383      if (!isset($arreglo[$id])) {
384        $new_fields[] = $id;
385      }
386    }
387    $form['#proyectos_operativos_fields'] = $new_fields;
388  }
389}
390
391/*
392 * Implementation of proyectos_operativos_proyecto_basico_form_submit().
393 * Guardar formulario de datos basicos (proyectos operativos).
394 */
395function _politicas_proyectos_basico_form_pd_submit($form, &$form_state) {
396  //se agregan los valores de descriptores, causas y cambios
397  $arreglo = array();
398  $arregloi = array();
399  $campos = array(
400    'descriptores' => array(
401       'value' => 'field_proyecto_problemas',
402       'nid' => 'field_proyectos_descript',
403     ),
404    'causas' => array(
405       'value' => 'field_proyecto_causas',
406       'nid' => 'field_proyectos_causasc',
407     ),
408    'cambios' => array(
409       'nid' => 'field_proyectos_cambios',
410     ),
411  );
412  $solucion = array();
413  foreach($campos as $id1 => $tipos) {
414    foreach($tipos as $valor => $campo) {
415      $arreglo = array();
416      foreach($form['#' . $id1] as $id => $nodo) {
417        $arreglo[][$valor] = $valor == 'nid'? $id : check_plain($nodo['body']);
418        if ($id1 == 'causas' && $valor == 'value') {
419          foreach($form['#formas_solucion'][$id] as $texto) {
420            $solucion[][$valor] = $texto;
421          }
422        }
423      }
424      $form_state['values'][$campo] = $arreglo;
425    }
426  }
427  //se agregan los valores de formas de solucion
428  $form_state['values']['field_proyectos_solucion'] = $solucion;
429  //se agregan los valores de plan de la patria
430  $pdlp = array();
431  for($i = 0; $i < 4 ; $i++) {
432    if (is_array($form['#pdlp'][$i])) {
433      foreach($form['#pdlp'][$i] as $id => $valor) {
434        if ($id) {
435          $pdlp[] = $id;
436        }
437      }
438    }
439  }
440  $form_state['values']['field_proyecto_pndes']['tids'] = $pdlp;
441  //carabobo
442  $arreglo = array();
443  foreach($form['#carabobo'] as $id => $valor) {
444    if ($id) {
445      $arreglo[]['value'] = $id;
446    }
447  }
448  $form_state['values']['field_proyectos_carabobo'] = $arreglo;
449  $form_state['values']['field_proyecto_mcti'] = array();
450  foreach($form['#politica'] as $politica) {
451    $form_state['values']['field_proyecto_mcti'][]['nid'] = $politica;
452  }
453}
454
455
456function _politicas_proyectos_display_politicas($descriptores, $formas_solucion) {
457  $output = '';
458  $arreglot = array(
459    'descriptores' => t('Problemas (Descriptores)'),
460    'causas' => t('Causas'),
461    'cambios' => t('Cambios en la Situación Actual'),
462  );
463  $solucion = array();
464  foreach($arreglot as $id1 => $texto) {
465    $output .= '<div id="proyectos-' . $id1 . '"><label for="edit-field-' . $id1 . '-value">' . $texto . ':</label>';
466    $arreglo = array();
467    foreach($descriptores[$id1] as $id => $nodo) {
468      $arreglo[] = $nodo['body'];
469      if ($id1 == 'causas') {
470        $solucion = array_merge($solucion, $formas_solucion[$id]);
471      }
472    }
473    $output .= theme('item_list', $arreglo);
474    $output .= '</div>';
475    if ($id1 == 'causas') {
476      $output .= '<div id="proyectos-solucion"><label for="edit-field-solucion-value">' . t('Formas de solución') . ':</label>';
477      $output .= theme('item_list', $solucion);
478      $output .= '</div>';
479    }
480  }
481  //pdlp
482  $output .= '<fieldset><legend>' . t('Plan de la Patria') . '</legend>';
483  $arreglo = array(t('Objetivos Históricos'), t('Objetivos Nacionales'), t('Objetivos Estratégicos'), t('Objetivos Generales'));
484  foreach($arreglo as $id => $texto) {
485    $output .= '<div id="proyectos-objetivo-' . $id . '"><label for="edit-field-proyectos-objetivo-' . $id . '-value">' . $texto . ':</label>';
486    $output .= theme('item_list', $descriptores['pdlp'][$id]);
487    $output .= '</div>';
488  }
489  $output .= '</fieldset>';
490  $output .= '<div id="proyectos-carabobo"><label for="edit-field-carabobo-value">' . t('Metas del Plan Campaña Carabobo') . ':</label>';
491  $output .= theme('item_list', $descriptores['carabobo']);
492  $output .= '</div>';
493  return $output;
494}
495
496function _politicas_proyectos_get_politicas_causas($politicas = array()) {
497  $causas = array();
498  if (count($politicas)) {
499    $sql = "SELECT p.field_politicas_causas_nid AS causa, p.nid FROM {content_field_politicas_causas} AS p INNER JOIN {node} AS n ON n.nid = p.nid AND n.vid = p.vid INNER JOIN {node} AS nc ON nc.nid = p.field_politicas_causas_nid INNER JOIN {content_type_causas} AS cc ON cc.nid = nc.nid AND cc.vid = nc.vid AND cc.field_causa_critica_value = '1' WHERE p.nid in(";
500    $inputs = array();
501    $implode_sql = array();
502    foreach($politicas as $id => $politica) {
503      $causas[$id] = array();
504      $implode_sql[] = '%d';
505      $inputs[] = $id;
506    }
507    $sql .= implode(', ', $implode_sql) . ')';
508    $result = db_query($sql, $inputs);
509    while($causa = db_fetch_object($result)) {
510      $causas[$causa->nid][$causa->causa] = $causa->causa;
511    }
512  }
513  return $causas;
514}
515
516/*
517 * Implementation of _politicas_proyectos_get_causas_all_causas()
518 * Obtiene las causas criticas por tipo de plan
519 */
520function _politicas_proyectos_get_causas_all_causas($tipo = 'posibles', $causas = array()){
521  $tabla = ($tipo == 'posibles')? 'content_field_descriptores_posibles' : 'content_field_descriptores_criticas';
522  $campo = 'field_descriptores_' . $tipo . '_nid';
523  $descriptores = array();
524  if (count($causas)) {
525    $sql = "SELECT d.*, ds." . $campo . " AS causa FROM {" . $tabla . "} AS ds INNER JOIN {content_type_descriptores} AS d ON d.nid = ds.nid AND d.vid = ds.vid INNER JOIN {node} AS n ON n.nid = ds.nid AND n.vid = ds.vid INNER JOIN {node} AS nc ON nc.nid = ds." . $campo . " INNER JOIN {content_type_causas} AS cc ON cc.nid = nc.nid AND cc.vid = nc.vid AND cc.field_causa_critica_value = '1' WHERE ";
526    $inputs = array();
527    foreach($causas as $causa) {
528      $implode_sql[] = '%d';
529      $inputs[] = $causa;
530    }
531    $sql .= ' ds.' . $campo . ' in (' . implode(', ', $implode_sql) . ')';
532    $result = db_query($sql, $inputs);
533    $descriptores = array();
534    while($descriptor = db_fetch_object($result)) {
535      if ($descriptor->nid && $descriptor->causa) {
536        $descriptores[$descriptor->causa][$descriptor->nid] = $descriptor->nid;
537      }
538    }
539  }
540  return $descriptores;
541}
542
543function politicas_proyectos_get_formas_solucion($causas = array()) {
544  $soluciones = array();
545  if (count($causas)) {
546    $implode_sql = array();
547    $inputs = array();
548    $sql = "SELECT c.field_causa_solucion_value as value, c.delta, c.nid FROM {content_field_causa_solucion} AS c INNER JOIN {node} AS n ON n.nid = c.nid AND n.vid = c.vid WHERE c.nid IN (";
549    foreach($causas as $causa) {
550      $implode_sql[] = '%d';
551      $inputs[] = $causa;
552    }
553    $sql .= implode(', ', $implode_sql) . ')';
554    $soluciones = array();
555    $result = db_query($sql, $inputs);
556    while($solucion = db_fetch_object($result)) {
557      $soluciones[$solucion->nid][$solucion->delta] = $solucion->value;
558    }
559  }
560  return $soluciones;
561}
562/**
563 * Implementation of hook_theme().
564 */
565function politicas_proyectos_theme() {
566  return array(
567    'politicas_direccionales_select' => array(
568      'arguments' => array('element' => NULL),
569    ),
570    'politicas_proyectos_formatter_body' => array(
571      'arguments' => array('element'),
572      'function' => 'theme_politicas_proyectos_formatter_body',
573    ),
574    'politicas_proyectos_formatter_pndes_0' => array(
575      'arguments' => array('element' => NULL, $html = TRUE, $unique = FALSE),
576      'function' => 'theme_politicas_proyectos_formatter_generic',
577    ),
578    'politicas_proyectos_formatter_pndes_1' => array(
579      'arguments' => array('element' => NULL, $html = TRUE, $unique = FALSE),
580      'function' => 'theme_politicas_proyectos_formatter_generic',
581    ),
582    'politicas_proyectos_formatter_pndes_2' => array(
583      'arguments' => array('element' => NULL, $html = TRUE, $unique = FALSE),
584      'function' => 'theme_politicas_proyectos_formatter_generic',
585    ),
586    'politicas_proyectos_formatter_pndes_3' => array(
587      'arguments' => array('element' => NULL, $html = TRUE, $unique = FALSE),
588      'function' => 'theme_politicas_proyectos_formatter_generic',
589    ),
590    'politicas_proyectos_formatter_pndeso_0' => array(
591      'arguments' => array('element' => NULL),
592      'function' => 'theme_politicas_proyectoso_formatter_generic',
593    ),
594    'politicas_proyectos_formatter_pndeso_1' => array(
595      'arguments' => array('element' => NULL),
596      'function' => 'theme_politicas_proyectoso_formatter_generic',
597    ),
598    'politicas_proyectos_formatter_pndeso_2' => array(
599      'arguments' => array('element' => NULL),
600      'function' => 'theme_politicas_proyectoso_formatter_generic',
601    ),
602    'politicas_proyectos_formatter_pndeso_3' => array(
603      'arguments' => array('element' => NULL),
604      'function' => 'theme_politicas_proyectoso_formatter_generic',
605    ),
606    'politicas_proyectos_formatter_pndesc_0' => array(
607      'arguments' => array('element' => NULL, $html = TRUE, $unique = FALSE),
608      'function' => 'theme_politicas_proyectos_formatter_generic',
609    ),
610    'politicas_proyectos_formatter_pndesc_1' => array(
611      'arguments' => array('element' => NULL, $html = TRUE, $unique = FALSE),
612      'function' => 'theme_politicas_proyectos_formatter_generic',
613    ),
614    'politicas_proyectos_formatter_pndesc_2' => array(
615      'arguments' => array('element' => NULL, $html = TRUE, $unique = FALSE),
616      'function' => 'theme_politicas_proyectos_formatter_generic',
617    ),
618    'politicas_proyectos_formatter_pndesc_3' => array(
619      'arguments' => array('element' => NULL, $html = TRUE, $unique = FALSE),
620      'function' => 'theme_politicas_proyectos_formatter_generic',
621    ),
622    'politicas_proyectos_formatter_metaspcc' => array(
623      'arguments' => array('element' => NULL),
624      'function' => 'theme_politicas_proyectos_formatter_metaspcc',
625    ),
626  );
627}
628
629/**
630 * Proxy theme function for 'full' and 'teaser' nodereference field formatters.
631 */
632function theme_politicas_proyectos_formatter_body($element) {
633  static $recursion_queue = array();
634  $output = '';
635  if (!empty($element['#item']['safe']['nid'])) {
636    $nid = $element['#item']['safe']['nid'];
637    $node = $element['#node'];
638    $field = content_fields($element['#field_name'], $element['#type_name']);
639    // If no 'referencing node' is set, we are starting a new 'reference thread'
640    if (!isset($node->referencing_node)) {
641      $recursion_queue = array();
642    }
643    $recursion_queue[] = $node->nid;
644    if (in_array($nid, $recursion_queue)) {
645      // Prevent infinite recursion caused by reference cycles:
646      // if the node has already been rendered earlier in this 'thread',
647      // we fall back to 'default' (node title) formatter.
648      return theme('nodereference_formatter_default', $element);
649    }
650    $referenced_node = _politicas_proyectos_load_politica($nid);
651    if ($referenced_node) {
652      $referenced_node->referencing_node = $node;
653      $referenced_node->referencing_field = $field;
654      $output = check_plain($referenced_node->body);
655    }
656  }
657  return $output;
658}
659
660/**
661 * Theme function for 'default' text field formatter.
662 */
663function theme_politicas_proyectos_formatter_metaspcc($element) {
664  foreach (element_children($element) as $key) {
665    if (isset($element[$key]['#item']['value'])) {
666      $selection[] = $element[$key]['#item']['value'];
667    }
668  }
669  $items = array();
670  foreach($selection as $value){
671    $term = taxonomy_get_term($value);
672    if ($term) {
673      $valores = term_fields_get_fields_values($term);
674      $items[] = check_plain($valores['plan_carabobo_meta_value']);
675    }
676  }
677  return theme('item_list', $items);
678}
679
680
681/**
682 * Theme function for HS Content Taxonomy formatters.
683 *
684 */
685function theme_politicas_proyectoso_formatter_generic($element) {
686  list($formatter, $level) = explode('_', $element['#formatter']);
687  $output = theme('politicas_proyectos_formatter_pndes_' . $level, $element, FALSE, TRUE);
688  return $output;
689}
690
691
692/**
693 * Theme function for HS Content Taxonomy formatters.
694 *
695 */
696function theme_politicas_proyectos_formatter_generic($element, $html = TRUE, $unique = FALSE) {
697  $output = '';
698  if (module_exists('hierarchical_select')) {
699    // Extract required field information.
700    // $element contains only field name; so we use cck function to get more info.
701    $field = content_fields($element['#field_name'], $element['#type_name']);
702    $field_name = $field['field_name'];
703    $vid        = $field['vid'];
704    $tid        = (empty($field['tid'])) ? 0 : $field['tid'];
705    $depth      = (empty($field['depth'])) ? 0 : $field['depth'];
706    // Get the config for this field.
707    require_once(drupal_get_path('module', 'hierarchical_select') .'/includes/common.inc');
708    $config_id = "content-taxonomy-$field_name";
709    $config = hierarchical_select_common_config_get($config_id);
710    $config += array(
711      'module' => 'hs_content_taxonomy_description',
712      'params' => array(
713        'vid'   => $vid,
714        'tid'   => $tid,
715        'depth' => $depth,
716      ),
717    );
718    $selection = array();
719    // Cycle through elements.
720    foreach (element_children($element) as $key) {
721      if (isset($element[$key]['#item']['value'])) {
722        $selection[] = $element[$key]['#item']['value'];
723      }
724    }
725    // It is said that formatter theme function is called even if field is empty.
726    if (empty($selection)) {
727      return $output;
728    }
729    // Generate a dropbox out of the selection. This will automatically
730    // calculate all lineages for us.
731    $dropbox = _hierarchical_select_dropbox_generate($config, $selection);
732    // Actual formatting.
733    // In 6.x formatter is fully themable
734    // We theme each lineage using additional theme function
735    $num_items = count($dropbox->lineages);
736    $flip = array('even' => 'odd', 'odd' => 'even');
737    $class = 'even';
738    $terms = array();
739    list($formatter, $level) = explode('_', $element['#formatter']);
740    $sufix = $html? '</li>' : '';
741    foreach ($dropbox->lineages as $i => $lineage) {
742      $term = isset($lineage[$level]['value']) ? taxonomy_get_term($lineage[$level]['value']) : 0;
743      if ($term && $term->tid && !isset($terms[$term->tid])) {
744        $terms[$term->tid] .= $formatter == 'pndes' || $formatter == 'pndeso'? $term->name : $term->name . HS_CONTENT_TAXONOMY_DESCRIPTION_SEP . $term->description;
745      }
746    }
747    if ($unique) {
748      //extract first element
749      $key = key($terms);
750      $new_array = array();
751      $new_array[$key] = $terms[$key];
752      $terms = $new_array;
753    }
754    $output = implode(' | ',$terms);
755    // Add the CSS.
756    //drupal_add_css(drupal_get_path('module', 'hierarchical_select') .'/hierarchical_select.css');
757  }
758  return $output;
759}
760
761/**
762 * Implementation of _politicas_proyectos_load_politica().
763 * Load node
764 */
765function _politicas_proyectos_load_politica($nid){
766  $node = 0;
767  if ($nid) {
768    $sql = 'SELECT n.nid, nr.body FROM {node} AS n INNER JOIN {node_revisions} AS nr ON nr.nid = n.nid AND nr.vid = n.vid WHERE n.nid = %d';
769    $result = db_query($sql, $nid);
770    $node = db_fetch_object($result);
771  }
772  return $node;
773}
774
775//----------------------------------------------------------------------------
776// CCK hooks.
777
778/**
779 * Implementation of hook_widget_info().
780 */
781function politicas_proyectos_widget_info() {
782  return array(
783    'politicas_direccionales_select' => array(
784      'label'       => 'Enlace a Politicas Direccionales',
785      'field types' => array('nodereference'),
786      'multiple values' => CONTENT_HANDLE_MODULE,
787      'callbacks' => array(
788        'default value' => CONTENT_CALLBACK_DEFAULT,
789      ),
790    ),
791  );
792}
793
794/**
795 * Implementation of hook_field_formatter_info().
796 */
797function politicas_proyectos_field_formatter_info() {
798  return array(
799    'body' => array(
800      'label' => t('Body'),
801      'field types' => array('nodereference'),
802      'multiple values' => CONTENT_HANDLE_CORE,
803    ),
804    'pndes_0' => array(
805      'label' => t('Nivel 0'),
806      'field types' => array('content_taxonomy'),
807      'multiple values' => CONTENT_HANDLE_MODULE,
808    ),
809    'pndes_1' => array(
810      'label' => t('Nivel 1'),
811      'field types' => array('content_taxonomy'),
812      'multiple values' => CONTENT_HANDLE_MODULE,
813    ),
814    'pndes_2' => array(
815      'label' => t('Nivel 2'),
816      'field types' => array('content_taxonomy'),
817      'multiple values' => CONTENT_HANDLE_MODULE,
818    ),
819    'pndes_3' => array(
820      'label' => t('Nivel 3'),
821      'field types' => array('content_taxonomy'),
822      'multiple values' => CONTENT_HANDLE_MODULE,
823    ),
824
825
826    'pndeso_0' => array(
827      'label' => t('Nivel 0 (ONAPRE)'),
828      'field types' => array('content_taxonomy'),
829      'multiple values' => CONTENT_HANDLE_MODULE,
830    ),
831    'pndeso_1' => array(
832      'label' => t('Nivel 1 (ONAPRE)'),
833      'field types' => array('content_taxonomy'),
834      'multiple values' => CONTENT_HANDLE_MODULE,
835    ),
836    'pndeso_2' => array(
837      'label' => t('Nivel 2 (ONAPRE)'),
838      'field types' => array('content_taxonomy'),
839      'multiple values' => CONTENT_HANDLE_MODULE,
840    ),
841    'pndeso_3' => array(
842      'label' => t('Nivel 3 (ONAPRE)'),
843      'field types' => array('content_taxonomy'),
844      'multiple values' => CONTENT_HANDLE_MODULE,
845    ),
846
847
848    'pndesc_0' => array(
849      'label' => t('Nivel 0 (Con Descripción)'),
850      'field types' => array('content_taxonomy'),
851      'multiple values' => CONTENT_HANDLE_MODULE,
852    ),
853    'pndesc_1' => array(
854      'label' => t('Nivel 1 (Con Descripción)'),
855      'field types' => array('content_taxonomy'),
856      'multiple values' => CONTENT_HANDLE_MODULE,
857    ),
858    'pndesc_2' => array(
859      'label' => t('Nivel 2 (Con Descripción)'),
860      'field types' => array('content_taxonomy'),
861      'multiple values' => CONTENT_HANDLE_MODULE,
862    ),
863    'pndesc_3' => array(
864      'label' => t('Nivel 3 (Con Descripción)'),
865      'field types' => array('content_taxonomy'),
866      'multiple values' => CONTENT_HANDLE_MODULE,
867    ),
868    'metaspcc' => array(
869      'label' => t('Metas del Plan Campaña de Carabobo'),
870      'field types' => array('content_taxonomy'),
871      'multiple values' => CONTENT_HANDLE_MODULE,
872    ),
873  );
874}
875
876/**
877 * Implementation of hook_widget_settings().
878 */
879function politicas_proyectos_widget_settings($op, $widget) {
880  switch ($op) {
881    case 'form':
882      $form = array();
883      $situacion_actual = isset($widget['situacion_actual']) ? $widget['situacion_actual'] : FALSE;
884      if ($widget['type'] == 'politicas_direccionales_select') {
885        $form['situacion_actual'] = array(
886          '#type' => 'checkbox',
887          '#title' => t('Permitir solo entes que tienen S.A:'),
888          '#default_value' => $situacion_actual,
889        );
890      }
891      else {
892        $form['situacion_actual'] = array('#type' => 'hidden', '#value' => $match);
893      }
894      return $form;
895
896    case 'save':
897      return array('situacion_actual');
898  }
899}
900
901/**
902 * Implementation of hook_widget().
903 *
904 * Attach a single form element to the form. It will be built out and
905 * validated in the callback(s) listed in hook_elements. We build it
906 * out in the callbacks rather than here in hook_widget so it can be
907 * plugged into any module that can provide it with valid
908 * $field information.
909 *
910 * Content module will set the weight, field name and delta values
911 * for each form element. This is a change from earlier CCK versions
912 * where the widget managed its own multiple values.
913 *
914 * If there are multiple values for this field, the content module will
915 * call this function as many times as needed.
916 *
917 * @param $form
918 *   the entire form array, $form['#node'] holds node information
919 * @param $form_state
920 *   the form_state, $form_state['values'][$field['field_name']]
921 *   holds the field's form values.
922 * @param $field
923 *   the field array
924 * @param $items
925 *   array of default values for this field
926 * @param $delta
927 *   the order of this item in the array of subelements (0, 1, 2, etc)
928 *
929 * @return
930 *   the form item for a single element for this field
931 */
932function politicas_proyectos_widget(&$form, &$form_state, $field, $items, $delta = 0) {
933  switch ($field['widget']['type']) {
934    case 'politicas_direccionales_select':
935      $element = array(
936        '#type' => 'politicas_direccionales_select',
937        '#default_value' => $items,
938      );
939      break;
940  }
941  return $element;
942}
943
944/**
945 * Implementation of FAPI hook_elements().
946 *
947 * Any FAPI callbacks needed for individual widgets can be declared here,
948 * and the element will be passed to those callbacks for processing.
949 *
950 * Drupal will automatically theme the element using a theme with
951 * the same name as the hook_elements key.
952 *
953 * Autocomplete_path is not used by text_widget but other widgets can use it
954 * (see nodereference and userreference).
955 */
956function politicas_proyectos_elements() {
957  return array(
958    'politicas_direccionales_select' => array(
959      '#input' => TRUE,
960      '#columns' => array('uid'), '#delta' => 0,
961      '#process' => array('politicas_direccionales_select_process'),
962    ),
963  );
964}
965
966/**
967 * FAPI theme for an individual elements.
968 *
969 * The textfield or select is already rendered by the
970 * textfield or select themes and the html output
971 * lives in $element['#children']. Override this theme to
972 * make custom changes to the output.
973 *
974 * $element['#field_name'] contains the field name
975 * $element['#delta]  is the position of this element in the group
976 */
977function theme_politicas_direccionales_select($element) {
978  return $element['#children'];
979}
980
981/**
982 * Process an individual element.
983 *
984 * Build the form element. When creating a form using FAPI #process,
985 * note that $element['#value'] is already set.
986 *
987 * The $fields array is in $form['#field_info'][$element['#field_name']].
988 */
989function politicas_direccionales_select_process($element, $edit, $form_state, $form) {
990  global $user;
991  $field_name = $element['#field_name'];
992  $field = $form['#field_info'][$field_name];
993  $field_key  = $element['#columns'][0];
994  $default = isset($element['#value'][$field_key]) ? $element['#value'][$field_key] : $form['#politica'];
995  $options = array();
996  if (!isset($form['#politicas']['politicas']) && count($form['#politicas']['politicas'])) {
997    $sa = isset($form['#field_info'][$element['#field_name']]['widget']['situacion_actual']) ? $form['#field_info'][$element['#field_name']]['widget']['situacion_actual'] : 0;
998    // The nodereference_select widget doesn't need to create its own
999    // element, it can wrap around the optionwidgets_select element.
1000    // This will create a new, nested instance of the field.
1001    // Add a validation step where the value can be unwrapped.
1002    $ente_nid = isset($form['#ente_planificador']) && isset($form['#ente_planificador']->nid) ? $form['#ente_planificador']->nid : 0;
1003    if (!$ente_nid) {
1004      $ente = usuario_tiene_ente($user->uid);
1005      $ente_nid = $ente->nid;
1006    }
1007    $field_key  = $element['#columns'][0];
1008    $politicas = _politicas_proyectos_references($ente_nid, $sa);
1009    $options = $politicas['politicas'];
1010  }
1011  else {
1012    $options = $form['#politicas']['politicas'];
1013   
1014  }
1015  $element[$field_key] = array(
1016    '#type' => 'select',
1017    '#title' => $element['#title'],
1018    '#description' => $element['#description'],
1019    '#required' => isset($element['#required']) ? $element['#required'] : $field['required'],
1020    '#multiple' => isset($element['#multiple']) ? $element['#multiple'] : $field['multiple'],
1021    '#options' => $options,
1022    '#default_value' => $default,
1023    '#entes' => $options['entes'],
1024  );
1025  if (isset($form['#politica'])) {
1026    $display = $form['#politica'] && count($form['#all_descriptores'])? _politicas_proyectos_display_politicas($form['#all_descriptores'], $form['#formas_solucion']) : t('No ha seleccionado una politica');
1027    if (!is_array($form['#politicas']['politicas']) || !count($form['#politicas']['politicas'])){
1028      $element[$field_key]['#prefix'] = '<div id="politicas-alert" class="color:red;font-weight: bold">' . t('El ente planificador aún no posee Políticas Direccionales.') . '</div>';
1029    }
1030
1031    $element[$field_key]['#suffix'] = '<div id ="proyecto-operativo-' . $field_key . '" class="form-item">' . $display . '</div>';
1032    $element[$field_key]['#ahah'] = array(
1033      'event' => 'change',
1034      'path' => 'politicas_proyectos_get_politicas_js',
1035      'wrapper' => 'proyecto-operativo-' . $field_key,
1036      'method' => 'replace',
1037      'progress' => array('type' => 'bar', 'message' => t('Please wait...')),
1038    );
1039
1040  }
1041  if (empty($element[$field_key]['#element_validate'])) {
1042    $element[$field_key]['#element_validate'] = array();
1043  }
1044  array_unshift($element[$field_key]['#element_validate'], 'nodereference_optionwidgets_validate');
1045  return $element;
1046}
1047
1048/**
1049 * Implementation of _politicas_direccionales_references().
1050 */
1051function _politicas_proyectos_references($ente_id = 0, $sa = 0) {
1052  static $results = array();
1053  if (!$results[$ente_id]) {
1054    $fathers = _ente_planificador_hierarchical_get_desc($ente_id, 1);
1055    if ($sa) {
1056      $planns = _situacion_actual_preliminar_get_planns();
1057      $plan = $planns['situacion_actual'];
1058    }
1059    $inputs = array();
1060    $implode_sql = array();
1061    $max_level = 0;
1062    foreach($fathers as $ente){
1063      if ($max_level < $ente['level']) {
1064        $max_level = $ente['level'];
1065      }
1066      if (!$sa) {
1067        $implode_sql[] = '%d';
1068        $inputs[] = $ente['nid'];
1069      }
1070      elseif (isset($plan['ente_type'][$ente['level']])) {
1071        $implode_sql[] = '%d';
1072        $inputs[] = $ente['nid'];
1073      }
1074    }
1075    //si el propio ente tiene politicas
1076    if (isset($plan['ente_type'][$max_level + 1])) {
1077      $implode_sql[] = '%d';
1078      $inputs[] = $ente_id;
1079    }
1080    $sql = 'SELECT n.nid, nr.body, pd.field_politicas_ente_nid FROM {content_type_politicas_direccionales} AS pd INNER JOIN {node} AS n ON n.nid = pd.nid AND n.vid = pd.vid INNER JOIN {node_revisions} AS nr ON n.nid = nr.nid AND n.vid = nr.vid WHERE';
1081    if (count($implode_sql)) {
1082      $sql .= ' pd.field_politicas_ente_nid IN (' . implode (', ', $implode_sql) . ') AND';
1083    }
1084    $sql .= ' field_politicas_direcc_year_value = %d AND field_politicas_seleccionada_value = %d';   
1085    $inputs[] = variable_get('situacional_actual_preliminar_anho_creacion', 0);
1086    $inputs[] = 1;
1087    $result = db_query($sql, $inputs);
1088    $results[$field['#ente_id']] = array();
1089    while($politica = db_fetch_object($result)) {
1090      $results[$ente_id]['politicas'][$politica->nid] = $politica->body;
1091      $results[$ente_id]['entes'][$politica->field_politicas_ente_nid] = $politica->field_politicas_ente_nid;
1092    }
1093  }
1094  return $results[$ente_id];
1095}
Nota: Vea TracBrowser para ayuda de uso del navegador del repositorio.