Search code examples
phpyiipchart

Fatal error: Cannot redeclare class pDraw


I am generating a pdf from the mPDF library using the Yii framework. For this PDF I need to add charts generated on the server, so I'm using the pChart library to generate them. I created a simple object class to set the pChart properties in an easier way for the PDF.

This is the class object:

<?php 
Class Chart {
    protected $fontsFolder = null;
    protected $data = array();
    protected $resolution = array();

    public $chartType = null;
    public $fontSize = 18;
    public $displayValues = false;
    public $dirFile = null;

    function __construct() {
        Yii::import('application.vendors.pChart.class.*', true);
        $this->fontsFolder = Yii::getPathOfALias('application.vendors.pChart.fonts');
    }

    // Set data points
    public function data($data) {
        if(!isset($data))
            throw new CException('Data array missing');

        if(!is_array($data))
            throw new CException('Data must be an array');

        $this->data[] = $data;
    }

    // Set label points
    public function labels($labels) {
        if(!isset($labels))
            throw new CException('Labels data must be assgined');
        if(!is_array($labels))
            throw new CException('Labels data must be an array');
        if(isset($this->data['labels']))
            throw new CException('Labels data is already assigned');
        $this->data['labels'] = $labels;
    }

    // Set resolution image
    public function resolution($x, $y) {
        if(isset($x) && isset($y)) {
            if(is_array($x) && is_array($y))
                throw new CException('Array to String error');
            $this->resolution['x'] = $x;
            $this->resolution['y'] = $y;
        } else
            throw new CException('Resolution data missing');
    }

    public function Debug() {
        var_dump($this->fontsFolder, $this->data, $this->resolution);
    }

    // Render chart with given data
    public function renderChart() {
        if(!$this->data)
            throw new CException('Data property must be assigned');

        if(!$this->resolution)
            throw new CException('Resolution property must be assigned');

        if(!$this->chartType)
            throw new CException('Chart type cannot be null');

        if(!$this->dirFile)
            throw new CException('Directory file must be assigned');

        $this->render();
    }


    protected function render() {
        switch ($this->chartType) {
            case 'lineChart':
                $this->lineChart();
                break;
            default:
                throw new CEXception('"'.$this->chartType.'" is not a valid chart type');
                break;
        }
    }

    protected function lineChart() {
        include('pDraw.class.php');
        include('pImage.class.php');
        include('pData.class.php');
        $data = new pData();
        foreach($this->data as $key => $value) {
            if(is_int($key))
                $data->addPoints($value);
        }
        $data->addPoints($this->data['labels'], 'labels');
        $data->setAbscissa('labels');
        $picture = new pImage($this->resolution['x'], $this->resolution['y'], $data);
        $picture->setFontProperties(array('FontName'=>$this->fontsFolder.'/Forgotte.ttf'), $this->fontSize);
        $picture->setGraphArea(60, 40, 970, 190);
        $picture->drawScale(array(
            'GridR'=>200,
            'GridG'=>200,
            'GridB'=>200,
            'DrawXLines'=>false
        ));
        $picture->drawLineChart(array('DisplayValues'=>$this->displayValues));
        $picture->render($this->dirFile);
    }
}
?>

And here is how I'm instantiating the object with PDF settings:

<?php 
Class SeguimientoController extends Controller {
    // public $layout = '//layouts/column2';

    public function actionIndex() {
        // Cargar libreria pdf y estilos
        $mPDF = Yii::app()->ePdf->mpdf();
        $mPDF->debug = true;
        $mPDF->showImageErrors = true;
        $stylesheet = file_get_contents(Yii::getPathOfAlias('webroot.css.reporte') . '/main.css');
        $mPDF->WriteHTML($stylesheet, 1);

        // Generate first chart
        $chart = new Chart;
        $chart->data(array(1,2,3,4,5));
        $chart->Labels(array('asd', 'dead', 'eads', 'daed', 'fasd'));
        $chart->resolution(1000, 200);
        $chart->chartType = 'lineChart';
        $chart->displayValues = true;
        $chart->dirFile = Yii::getPathOfAlias('webroot.images').'/chart.png';
        $chart->renderChart();
        $mPDF->WriteHTml(CHtml::image('/basedato1/images/chart.png', 'chart'), 2);

        // Generate second chart
        $chart1 = new Chart;
        $chart1->data(array(1,2,3,4,5));
        $chart1->Labels(array('asd', 'dead', 'eads', 'daed', 'fasd'));
        $chart1->resolution(1000, 200);
        $chart1->chartType = 'lineChart';
        $chart1->displayValues = true;
        $chart1->dirFile = Yii::getPathOfAlias('webroot.images').'/chart.png';
        $chart1->renderChart();
        $mPDF->WriteHTml(CHtml::image('/basedato1/images/chart.png', 'chart'), 2);
        $mPDF->OutPut();
    }
}
?>

By testing the output of the view step by step, everything goes fine, the chart is rendered and saved as a temp file so the pdf can gather it. But when I have to render the second chart, I get a fatal error.

I have tried creating another class to be accessed by static functions because I thought the error could be made from multiple instances of the same object. But again, on second render I get the same error.

Just in case, if you need to know how the error outputs, here it is: Fatal error: Cannot redeclare class pDraw in C:\Servidor\basedato1\protected\vendors\pChart\class\pDraw.class.php on line 104.


Solution

  • Use include_once instead of include.

    include_once('pDraw.class.php');
    include_once('pImage.class.php');
    include_once('pData.class.php');