Source for file export.php

Documentation is available at export.php

  1. <?php
  2. /**
  3. * Export various views of the booking data in numerous formats
  4. *
  5. @author    Stuart Prescott
  6. @copyright  Copyright Stuart Prescott
  7. @license    http://opensource.org/licenses/gpl-license.php GNU Public License
  8. @version    $Id$
  9. @package    Bumblebee
  10. @subpackage Actions
  11. *
  12. *  path (bumblebee root)/inc/actions/export.php
  13. */
  14.  
  15. /** Load ancillary functions */
  16. require_once 'inc/typeinfo.php';
  17.  
  18. require_once 'inc/bb/configreader.php';
  19.  
  20. /** CheckBox object */
  21. require_once 'inc/formslib/checkbox.php';
  22. /** CheckBoxTableList object */
  23. require_once 'inc/formslib/checkboxtablelist.php';
  24. /** Data reflector object */
  25. require_once 'inc/formslib/datareflector.php';
  26. /** parent object */
  27. require_once 'inc/actions/bufferedaction.php';
  28. /** Export formatting codes */
  29. require_once 'inc/exportcodes.php';
  30. /** Export configuration and formatting */
  31. require_once 'inc/export/exporttypes.php';
  32. /** Export method object */
  33. require_once 'inc/export/arrayexport.php';
  34. /** Export method object */
  35. require_once 'inc/export/htmlexport.php';
  36. /** database interrogation object */
  37. require_once 'inc/formslib/dblist.php';
  38. /** list of choices */
  39. require_once 'inc/formslib/anchortablelist.php';
  40. /** list of choices */
  41. require_once 'inc/bb/daterange.php';
  42. /** list of choices */
  43. require_once 'inc/formslib/radiolist.php';
  44.  
  45. /**
  46. * Export various views of the booking data in numerous formats
  47. *
  48. * A number of different data views can be created (see exporttypes.php)
  49. * and the data can be exported in various formats (see htmlexport.php and arrayexport.php)
  50. *
  51. * This class is inherited by other exporters
  52. @package    Bumblebee
  53. @subpackage Actions
  54. */
  55. class ActionExport extends BufferedAction {
  56.   /**
  57.   * forces SQL errors to be fatal
  58.   * @var    boolean 
  59.   */
  60.   var $fatal_sql = 1;
  61.   /**
  62.   * name of the export format to be used
  63.   * @var    string 
  64.   */
  65.   var $format;
  66.   /**
  67.   * object containing export SQL and formatting instructions
  68.   * @var    ExportTypeList 
  69.   */
  70.   var $typelist;
  71.   /**
  72.   * the specific ExportType to be used in this data export
  73.   * @var    ExportType 
  74.   */
  75.   var $_export;  // ExportType format description
  76.     /**
  77.   * The data range to be used for data export
  78.   * @var    DateRange 
  79.   */
  80.   var $_daterange;
  81.   /**
  82.   * The original action word (verb!) that instantiated this class (not its descendants)
  83.   * Allows HTML links back to this class to be easily made.
  84.   * @var    string 
  85.   */
  86.   var $_verb = 'export';
  87.  
  88.   /**
  89.   * Initialising the class
  90.   *
  91.   * @param  BumblebeeAuth $auth  Authorisation object
  92.   * @param  array $pdata   extra state data from the call path
  93.   * @return void nothing
  94.   */
  95.   function ActionExport($auth$pdata{
  96.     parent::BufferedAction($auth$pdata);
  97.   }
  98.  
  99.   function go({
  100.     $reflector new DataReflector();
  101.     echo $reflector->display($this->PD);
  102.  
  103.     $this->typelist = new ExportTypeList();
  104. //     preDump($this->typelist);
  105.     if (isset($this->PD['what'])) {
  106.       $this->unbuffer();
  107.       $this->selectExport();
  108.     else {
  109.       $allDataOK true;
  110.       $this->_daterange = new DateRange('daterange'T_('Select date range'),
  111.                       T_('Enter the dates over which you want to export data'));
  112.       $this->_daterange->update($this->PD);
  113.       $this->_daterange->checkValid();
  114.       $this->_daterange->reflectData = 0;
  115.       $this->_daterange->includeSubmitButton = 0;
  116.       if ($this->_daterange->newObject || !$this->_daterange->isValid{
  117.         #echo "don't have date range <br />";
  118.         $allDataOK false;
  119.         $this->unbuffer();
  120.         $this->_daterange->setDefaults(DR_PREVIOUSDR_QUARTER);
  121.         echo $this->_daterange->display($this->PD);
  122.       }
  123.       if (isset($this->format)) {
  124.         #echo "don't have format<br />";
  125.         $allDataOK false;
  126.         $this->unbuffer();
  127.         $this->formatSelect();
  128.       }
  129.       if (isset($this->PD['limitationselected'])) {
  130.         #echo "don't have instruments <br />";
  131.         $allDataOK false;
  132.         $this->unbuffer();
  133.         $this->outputSelect();
  134.       }
  135.       if ($allDataOK{
  136.         echo $this->reportAction($this->returnExport(),
  137.               array(STATUS_ERR =>  T_('Error exporting data:').' '.$this->errorMessage
  138.                    )
  139.              );
  140.       else {
  141.         $this->_goButton();
  142.       }
  143.     }
  144.   }
  145.  
  146.   function mungeInputData({
  147.     parent::mungeInputData();
  148.     if (isset($this->PD['outputformat'])) {
  149.       $this->format = $this->PD['outputformat'];
  150.     }
  151.   }
  152.  
  153.   /**
  154.   * Generate HTML list for user to select which data export should be used
  155.   *
  156.   * @return void nothing
  157.   */
  158.   function selectExport({
  159.     $reportlist array();
  160.     foreach ($this->typelist->types as $type{
  161.       $reportlist[$type->name$type->description;
  162.     }
  163.     $select new AnchorTableList('datasource'T_('Select which data to export')1);
  164.     $select->setValuesArray($reportlist'id''iv');
  165.     $select->hrefbase makeURL($this->_verbarray('what'=>'__id__'));
  166.     $select->setFormat('id''%s'array('iv'));
  167.     echo $select->display();
  168.   }
  169.  
  170.   /**
  171.   * Generate HTML list for user to select which data format should be used
  172.   *
  173.   * @return void nothing
  174.   */
  175.   function formatSelect({
  176.     $conf ConfigReader::getInstance();
  177.     $formatlist array(EXPORT_FORMAT_VIEW     => T_('View in web browser'),
  178.                         EXPORT_FORMAT_VIEWOPEN => T_('View in web browser (new window)'),
  179.                         EXPORT_FORMAT_CSV      => T_('Save as comma separated variable (csv)'),
  180.                         EXPORT_FORMAT_TAB      => T_('Save as tab separated variable (txt)'));
  181.     if ($conf->value('export''enablePDF')) {
  182.       $formatlist[EXPORT_FORMAT_PDFT_('Save as pdf report');
  183.     }
  184.     $select new RadioList('outputformat'T_('Select which data to export')1);
  185.     $select->setValuesArray($formatlist'id''iv');
  186.     $select->setFormat('id''%s'array('iv'));
  187.     if (is_numeric($conf->value('export''defaultFormat'))) {
  188.       $select->setDefault($conf->value('export''defaultFormat'));
  189.     else {
  190.       $select->setDefault(exportStringToCode($conf->value('export''defaultFormat')));
  191.     }
  192.     echo '<div style="margin: 2em 0 2em 0;">'.$select->display().'</div>';
  193.   }
  194.  
  195.   /**
  196.   * Generate HTML form widget for user to control output.
  197.   *
  198.   * User can select which sub-view of the data to use
  199.   * and which specific parts of the data should be included (i.e. restrict by group)
  200.   *
  201.   * @return void nothing
  202.   */
  203.   function outputSelect({
  204.     $export $this->typelist->types[$this->PD['what']];
  205.     for ($lim 0$lim count($export->limitation)$lim++{
  206.       $select new CheckBoxTableList('limitation-'.$limT_('Select which detail to view'));
  207.       $hidden new TextField($export->limitation[$lim]);
  208.       $select->addFollowHidden($hidden);
  209.       $chosen new CheckBox('selected'T_('Selected'));
  210.       $select->addCheckBox($chosen);
  211.       //$select->numSpareCols = 1;
  212.       if ($export->limitation[$lim== 'users'{
  213.         $select->connectDB($export->limitation[$lim]array('id''name''username'));
  214.         $select->setFormat('id''%s'array('name')" (%s)"array('username'));
  215.       else {
  216.         $select->connectDB($export->limitation[$lim]array('id''name''longname'));
  217.         $select->setFormat('id''%s'array('name')" %50.50s"array('longname'));
  218.       }
  219.       $select->addSelectAllFooter(true);
  220.       echo $select->display().'<br/>';
  221.     }
  222.     if (is_array($export->pivot&& count($export->pivot1{
  223.       $views array();
  224.       foreach ($export->pivot as $k => $v{
  225.         $views[$k$v['description'];
  226.       }
  227.       $viewselect new RadioList('pivot'T_('Select which data view to export')1);
  228.       $viewselect->setValuesArray($views'id''iv');
  229.       $viewselect->setFormat('id''%s'array('iv'));
  230.       reset($views);
  231.       $viewselect->setDefault(key($views));
  232.       echo '<div style="margin: 0em 0 2em 0;">'.$viewselect->display().'</div>';
  233.     }
  234.     echo '<input type="hidden" name="limitationselected" value="1" />';
  235.   }
  236.  
  237.   /**
  238.   * Common submit button for this class
  239.   *
  240.   * @return void nothing
  241.   */
  242.   function _goButton({
  243.     echo '<input type="submit" name="submit" value="'.T_('Select').'" />';
  244.   }
  245.  
  246.   /**
  247.   * Generate the data export and then send it to the user in the appropriate format
  248.   *
  249.   * @return void nothing
  250.   */
  251.   function returnExport({
  252.     $list $this->_getDataList($this->PD['what']);
  253.     $list->fill();
  254.     if (count($list->data== 0{
  255.       return $this->unbufferForError('<p>'.T_('No data found for those criteria').'</p>');
  256.     }
  257.     // start rendering the data
  258.     $list->outputFormat $this->format;
  259.     $list->formatList();
  260.     if ($this->format EXPORT_FORMAT_USEARRAY{
  261.       $exportArray new ArrayExport($list$list->breakfield);
  262.       $exportArray->header $this->_reportHeader();
  263.       $exportArray->author $this->auth->name;
  264.       $exportArray->makeExportArray();
  265.       //preDump($exportArray->export);
  266.     }
  267.     if ($this->format EXPORT_FORMAT_USEHTML{
  268.       $htmlExport new HTMLExport($exportArray);
  269.       $htmlExport->makeHTMLBuffer();
  270.     }
  271.  
  272.     //finally, direct the data towards its output
  273.     if ($this->format == EXPORT_FORMAT_PDF){
  274.       // construct the PDF from $htmlbuffer
  275.       $pdfExport $this->_preparePDFExport($exportArray);
  276.       $pdfExport->makePDFBuffer();
  277.  
  278.       if ($pdfExport->writeToFile{
  279.         $this->unbuffer();
  280.       else {
  281.         $this->_getFilename();
  282.         $this->bufferedStream =$pdfExport->export;
  283.         // the data itself will be dumped later by the action driver (index.php)
  284.       }
  285.     elseif ($this->format EXPORT_FORMAT_DELIMITED{
  286.       $this->_getFilename();
  287.       $this->bufferedStream = '"'.$this->_reportHeader().'"'."\n"
  288.                                .$list->outputHeader()."\n"
  289.                                .join($list->formatdata"\n");
  290.       // the data itself will be dumped later by the action driver (index.php)
  291.     elseif ($this->format == EXPORT_FORMAT_VIEWOPEN{
  292.       $this->unbuffer();
  293.       echo $htmlExport->wrapHTMLBuffer();
  294.     else {
  295.       $this->unbuffer();
  296.       echo $htmlExport->export;
  297.     }
  298.   }
  299.  
  300.   /**
  301.   * Sets up the DBlist object so that it can query the db
  302.   *
  303.   * @return DBList query ready to run
  304.   */
  305.   function _getDataList($report{
  306.     $this->_export = $this->typelist->types[$report];
  307.     $start $this->_daterange->getStart();
  308.     $stop  clone($this->_daterange->getStop());
  309.     $stop->addDays(1);
  310.  
  311.     if (is_array($this->_export->union&& count($this->_export->union)) {
  312.       $union array();
  313.       $limitsOffset 0;
  314.       foreach ($this->_export->union as $export{
  315.         $union[$this->_getDBListFromExport($export$start$stop$limitsOffset);
  316.         $limitsOffset += count($export->limitation);
  317.       }
  318.       $list $this->_getDBListFromExport($this->_export$start$stop);
  319.       $list->union $union;
  320.     else {
  321.       $list $this->_getDBListFromExport($this->_export$start$stop);
  322.     }
  323.     return $list;
  324.   }
  325.  
  326.   /**
  327.   * From the export definition in the ExportType generate a DBList query
  328.   *
  329.   * @return void DBList ready for query
  330.   */
  331.   function _getDBListFromExport(&$export$start$stop$limitsOffset=0{
  332.     $where $export->where;
  333.     $where[$export->timewhere[0].qw($start->dateTimeString());
  334.     $where[$export->timewhere[1].qw($stop->dateTimeString());
  335.     $where array_merge($where$this->_limitationSet($export->limitation$limitsOffset));
  336.     // work out what view/pivot of the data we want to see
  337.     if (count($export->limitation&& is_array($export->pivot)) {
  338.       $pivot $export->pivot[$this->PD['pivot']];
  339.       $export->group      $pivot['group'];
  340.       $export->omitFields array_flip($pivot['omitFields']);
  341.       $export->breakField $pivot['breakField'];
  342.       if (isset($pivot['fieldOrder']&& is_array($pivot['fieldOrder'])) {
  343.         $export->fieldOrder $pivot['fieldOrder'];
  344.       }
  345.       if (isset($pivot['extraFields']&& is_array($pivot['extraFields'])) {
  346.         $export->fields array_merge($export->fields$pivot['extraFields']);
  347.       }
  348.     }
  349.     $list new DBList($export->basetable$export->fieldsjoin($where' AND '));
  350.     $list->join        array_merge($list->join$export->join);
  351.     $list->group       $export->group;
  352.     $list->manualGroup $export->manualGroup;
  353.     $list->manualSum   $export->manualSum;
  354.     $list->order       $export->order;
  355.     $list->distinct    $export->distinct;
  356.     $list->fieldOrder  $export->fieldOrder;
  357.     $list->breakfield  $export->breakField;
  358.     if ($this->format EXPORT_FORMAT_USEARRAY{
  359.       $list->omitFields $export->omitFields;
  360.     }
  361.     return $list;
  362.   }
  363.  
  364.   /**
  365.   * Determine what limitation should be applied to the broad query
  366.   *
  367.   * @todo //TODO:   there are limitations in the IN() syntax.... replace this with lots of booleans?
  368.   *
  369.   * @return array SQL field IN (list...) syntax
  370.   */
  371.   function _limitationSet($fields$limitsOffset$makeSQL=true{
  372.     $sets array();
  373.     for ($lim 0$lim count($fields)$lim++{
  374.       $limitation array();
  375.       $fieldpattern '/^limitation\-(\d+)\-(\d+)\-'.$fields[$lim].'$/';
  376.       $selected array_values(preg_grep($fieldpatternarray_keys($this->PD)));
  377.       #preDump($selected);
  378.       for ($j=0$j count($selected)$j++{
  379.         $ids array();
  380.         preg_match($fieldpattern$selected[$j]$ids);
  381.         $item issetSet($this->PD,$selected[$j]);
  382.         if (issetSet($this->PD,'limitation-'.$ids[1].'-'.$ids[2].'-selected'&& $item !== NULL{
  383.           $limitation[/*$export->limitation[$lim].'.id='.*/qw($item);
  384.         }
  385.         //echo $namebase.':'.$j.':'.$lim.':'.$fields[$lim].':'.$item.'<br/>';
  386.       }
  387.       if (count($limitation)) {
  388.         if ($makeSQL{
  389.           $sets[$fields[$lim].'.id IN ('.join($limitation', ').')';
  390.         else {
  391.           $sets[$fields[$lim]] $limitation;
  392.         }
  393.       }
  394.       //preDump($limitation);
  395.     }
  396.     return $sets;
  397.   }
  398.  
  399.   /**
  400.   * Set the filename and mimetype for the data export
  401.   *
  402.   * @return void nothing
  403.   */
  404.   function _getFilename({
  405.     switch ($this->format EXPORT_FORMAT_MASK{
  406.       case EXPORT_FORMAT_CSV:
  407.         $ext 'csv';
  408.         $type 'text/csv';
  409.         break;
  410.       case EXPORT_FORMAT_TAB:
  411.         $ext 'txt';
  412.         $type 'text/tab-separated-values';
  413.         //$type = 'application/vnd-excel';
  414.         break;
  415.       case EXPORT_FORMAT_PDF:
  416.         $ext 'pdf';
  417.         $type 'application/pdf';
  418.         break;
  419.       default:
  420.         $ext '';
  421.         $type 'application/octet-stream';
  422.     }
  423.     $this->filename = parent::getFilename('export'$this->PD['what']$ext);
  424.     $this->mimetype = $type;
  425.   }
  426.  
  427.   /**
  428.   * Generate the PDF for return to the user
  429.   *
  430.   * @uses PDFExport but only loaded here so that optional library can be absent without compile errors
  431.   * @return string $pdf containing the PDF
  432.   */
  433.   function _preparePDFExport(&$exportArray{
  434.     require_once('inc/export/pdfexport.php');
  435.     $pdf new PDFExport($exportArray);
  436.     return $pdf;
  437.   }
  438.  
  439.   /**
  440.   * Generate the standard report header from the date range and the description in ExportType
  441.   *
  442.   * @return string the title to be used for this report
  443.   */
  444.   function _reportHeader({
  445.     $start $this->_daterange->getStart();
  446.     $stop  $this->_daterange->getStop();
  447.     $s sprintf($this->_export->header$start->getShortDateString()$stop->getShortDateString());
  448.     return $s;
  449.   }
  450.  
  451. }  //ActionExport
  452. ?>

Documentation generated on Tue, 06 Mar 2007 10:01:25 +0000 by phpDocumentor 1.3.0