Two other similar questions required Properties not to be Private (Undefined Property in Class Inheritance?) and a call to the Parent Constructor (Undefined property when accessing properties from a parent class), these are not the issues in my case.
I have an inherited class that is the Object instance, but I am calling a function that is provided by the parent which accesses it's own protected property.
In one object the code actually works, unless I make a separate function call (see code below), in which case I get this error, in another class I get the error when running sendExport() even without the extra line to force the issue (the error is embedded in the returned Excel which is corrupted).
I cannot see any difference between my child classes so I don't know why the behaviour is different, and even though one works for my need, the fact that it can generate an error makes me nervous, so any pointers on possible issues/fix would be great.
The error is:
Undefined property: App\Helpers\Exports\StudyExport::$spreadsheet at ExcelReport.php:20
Line 20 is: if($this->spreadsheet instanceof Spreadsheet){
This is the Parent class ExcelReport.php, the sendExport() is the function to look at, which calls getExcel(), You'll note there is no constructor call required:
<?php
namespace App\Helpers;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use Illuminate\Support\Facades\Auth;
class ExcelReport
{
protected $cellRow=0;
protected $count=0;
protected $excelSec=1/24/60/60;
protected $spreadsheet=null;
public function checkExcel(){
return $this->spreadsheet instanceof Spreadsheet;
}
public function getExcel($tab=0){
if($this->spreadsheet instanceof Spreadsheet){
if($tab>=$this->spreadsheet->getSheetCount()) $tab=0;
$this->spreadsheet->setActiveSheetIndex($tab);
$writer=new Xlsx($this->spreadsheet);
ob_start();
$writer->save('php://output');
$this->spreadsheet->disconnectWorksheets();
unset($this->spreadsheet);
return ob_get_contents();
}else{
return $this->spreadsheet;
}
}
public function sendExport($title,$tab=0){
$filename=$this->filename($title,Auth::user()->dateFormat()).'.xlsx';
// This line is not actually needed, without it, the code works (in one child but not in
// another), with it the call to getExcel() gives the error
$this->getExcel($tab);
// /////
return response()->streamDownload(
function () use ($tab) { $this->getExcel($tab);},
$filename,
[
'Content-Type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'Cache-Control' => 'max-age=0'
]
);
}
protected function getSheet(){
if(is_null($this->spreadsheet)) $this->spreadsheet=new Spreadsheet();
else $this->spreadsheet->createSheet();
$this->cellRow=$this->count=0;
return $this->spreadsheet->setActiveSheetIndex($this->spreadsheet->getSheetCount()-1);
}
protected function getCol($num){
$letter = chr(65 + ($num % 26));
$num2 = intval($num / 26);
return ($num2 > 0)
? $this->getCol($num2 - 1) . $letter
: $letter;
}
protected function toExcelTime($sec){
return $sec*$this->excelSec;
}
private function filename($title, $format='d-m-Y'){
$today=new \DateTime();
$title= substr(
str_replace(
array_merge(
array_map('chr', range(0,31)),["<", ">", ":", '"', "/", "\\", "|", "?", "*"]
),
"_",
$title
)
,0,100);
return $title.' '.$today->format($format);
}
}
The child class code is not really relevant but of course they are defined with extends
use App\Helpers\ExcelReport;
class StudyExport extends ExcelReport
{