PHP code problem with mpdf library


#1

This is the sample code

if ($office[‘office_code’] == 15);
{
if ($divisions[‘order_id’] == 0);

		{
			$pdf->SetXY(122,190);
			$pdf->Write(0,'Head Office 15');
		}
	
	}
	if ($office['office_code'] == 15);
	{
		if ($divisions['order_id'] == 1);
		
		{
			$pdf->SetXY(122,190);
			$pdf->Write(0,'Division Head');
		}
	
	}

This data from this code will be printed as pdf file thru mpdf library.
This code is from my leave page, I want that if Employee is from office 15 the signatory will be Head Office 15 and if Employee is from Division 1 which also under Office 15 the signatory will be Division Head instead of Head Office 15.


#2

Firstly, your conditional logic isn’t working because you have semi-colons ; on the end of each if(…); statement. These should be removed, as they are ending the if() logic and all the statements inside the {…} are being unconditionally executed.

Next, a question. Is there (going to be) a bunch of other logic to do things for other office code and division values? If so, you should not be writing out conditional logic to handle each possible set of values, as this will result in a hard to write, test, debug, and maintain wall of code, that requires you to find and edit the code each time new values get added, changed, or removed. What you should do instead is use a data driven design, where you define the mapping of input values to output values in a data structure (array or database table), then simply use the input values to match and retrieve the corresponding output values.

Lastly, Don’t Repeat Yourself (DRY). You should only write program logic for things that are dynamic. The only thing the above code is doing that is dynamic is producing the string to write at that xy location. It should use whatever method you decide on to produce the string, store the result in a variable, then use that variable in one instance of the code that produces the output.


#3

There are about 15 Office and 2 Divisions in our organization. Each of them has a signatory. So do I need to write about 17 if statements for these?


#4

If you post some examples of $office[‘office_code’] and $divisions[‘order_id’] values, and what the resultant signatory value should be for each, this will define the limits and rules to use, so that someone can post example code. As it is, the one example implied in your existing code doesn’t tell us what exact result you expect for all possibilities.


#5

My example is
if ($office[‘office_code’] == 15); which is Mayors Office
The signatory of this is Meriam Dumlao

if ($divisions[‘order_id’] == 1); This is HR Division which is also under Mayors Office
The signatory of this is Jonathan Vega

Now what I want to do is if employee from HR will file a leave of absence the Signatory will be Jonathan but when I try it outputted Meriam Dumlao.


#6

Well, just fixing the errors in the sample code you showed us might help.

First, if a semi-colon is used at the end of the IF clause, it ends the statement at that point. Then, the next brace is ALWAYS executed as it is just code NOT within the IF clause. Do you understand that part?

Next, PHDR explained that you could use a “data driven” design instead. If you have 17 different possible results to display, you could make a table of them and just use simple indexing to pull out the results. If you must use 17 different compares, fix the IF clauses and it will work.

if ($office[‘office_code’] == 15)
     {
          if ($divisions[‘order_id’] == 0)
                {
		     $pdf->SetXY(122,190);
		     $pdf->Write(0,'Head Office 15');
		}
	}
	if ($office['office_code'] == 15)
               {
		     if ($divisions['order_id'] == 1)
                 {
			         $pdf->SetXY(122,190);
			         $pdf->Write(0,'Division Head');
		     } elseif($divisions['order_id'] == 2) {
			         $pdf->SetXY(122,190);
			         $pdf->Write(0,'SOME OTHER HEAD FOR #2');
	            }

Now, with that fixed code shown to you, you must see clearly that you are repeating a lot of code.
You keep doing tests and setting up the $pdf-> values over and over and guessing 17 times.
If you just place all of this into an array or DB table, you can replace ALL of this code with just a simple one to three lines of code. One if you use an array, three or four if you use a query to a DB table.

So, PHDR was correct that you should look at a data-driven solution instead of all the nested IF clauses.
Do you understand these options and how they would work? If not we can help explain it further…


#7

Your single example, using the same values as in the 1st post in this thread, still doesn’t tell us anything about some of the other possibilities, so the following example code may or may not help you -

// define the mapping of office code/order id to signatory values
$sig_map = [];
$sig_map['15|0'] = 'Meriam Dumlao';
$sig_map['15|1'] = 'Jonathan Vega';
// add elements to this array for other combinations ...

// form an index consisting of the office code and order id value
$index = $office['office_code'] .'|'. $divisions['order_id'];

// given the index value, retrieve the signatory value
$signature = $sig_map[$index];

// output the data
$pdf->SetXY(122,190);
$pdf->Write(0,$signature);

#8

Ha! PHDR, I was going to let him figure it out after he understood the IF clause ending incorrectly…
Yours was very nice! I think he should understand that!


#9

Just want to point out that in this example the empty array is not necessary.


#10

Here’s full code sir PHDR

function leave_apps($leave_apps_id = '')
{
	$lgu_code = $this->Settings->get_selected_field('lgu_code'); 
	
	
	if ( $lgu_code == 'Calabarzon' )
	{

		$this->leave_apps_calabarzon($leave_apps_id);
		
		return;
	}
	
	$rows = $this->Leave_apps->get_leave_apps_info($leave_apps_id);

	$name = $this->Employee->get_employee_info($rows['employee_id']);
	
	$office_name = $this->Office->get_office_name($name['office_id']);
	
	
	$this->load->library('fpdf');
	
	define('FPDF_FONTPATH',$this->config->item('fonts_path'));
					
	$this->load->library('fpdi');
	
	// initiate FPDI   
	$pdf = new FPDI('P', 'mm', 'A4');
	
	// add a page
	$pdf->AddPage();
	
	// set the sourcefile
	$pdf->setSourceFile('dtr/template/APPLICATION_FOR_LEAVE.pdf');
	
	// select the first page
	$tplIdx = $pdf->importPage(1);
	
	// use the page we imported
	$pdf->useTemplate($tplIdx);
	
	// set font, font style, font size.
	$pdf->SetFont('Arial','B',12);
	
	
	// set initial placement
	$pdf->SetXY(158,10.5);
	
	// line break
	//$pdf->Ln(40);
	
	$pdf->Write(0, 'Tracking no: '.$leave_apps_id);
	$pdf->Ln(9);
	$pdf->SetX(158);
	
	//ID number
	$pdf->Write(0, ' '.$rows['employee_id']);
	
	$pdf->Ln(20);
	
	// go to 25 X (indent)
	$pdf->SetX(25);
	
	$this->Office->fields = array('office_code');
	
	$office = $this->Office->get_office_info($name['office_id']);
	
	// write office
	$pdf->Write(0, $office['office_code']);
	
	//lname
	$pdf->SetX(90);
	$pdf->Write(0, $name['lname']);
	
	//fname
	$pdf->SetX(145);
	$pdf->Write(0, $name['fname']);
	
	//mname
	$pdf->SetX(192);
	$pdf->Write(0, $name['mname'][0].'.');
	
	$pdf->Ln(13);
	
	//date of file
	$pdf->SetX(25);
	$pdf->Write(0, date("F d, Y", strtotime($rows['date_encode'])));
	
	//position
	$pdf->SetX(70);
	$pdf->Write(0, $name['position']);
	
	// We need to check what salary grade the office use
	if ( $office['salary_grade_type'] == 'hospital' )
	{
		$this->Salary_grade->salary_grade_type = 'hospital';
	}
	
	//monthly salary
	$pdf->SetX(170);
	$pdf->Write(0, 'P '.number_format($this->Salary_grade->get_monthly_salary($name['salary_grade'], $name['step']), 2));
	
	
	$pdf->Ln(14);
	
	$leave_name = $this->Leave_type->get_leave_name($rows['leave_type_id']);
	
	$leave_type_ids = array(1, 3, 4, 5, 6, 7, 9, 10, 12);
	
	if (in_array($rows['leave_type_id'], $leave_type_ids))
	{
		$pdf->Ln(2);
		$pdf->SetX(28);
		$pdf->Write(0, 'X');
		
		$pdf->Ln(18);
		
		$pdf->SetX(32);
		
		if ( $rows['leave_type_id'] == 1 )
		{
			$leave_name = '';
		}
		
		$pdf->SetFont('Arial','B',10);
		$pdf->Write(0, $leave_name);
		$pdf->SetFont('Arial','B',12);
	}
	
	$leave_type_ids = array(2, 11, 20);
	
	if (in_array($rows['leave_type_id'], $leave_type_ids))
	{
		$pdf->Ln(27);
		$pdf->SetX(28);
		$pdf->Write(0, 'X');
		
		$pdf->Ln(18);
		
		$pdf->SetX(32);
		
		if ( $rows['leave_type_id'] == 2 )
		{
			$leave_name = '';
		}
		
		$pdf->SetFont('Arial','B',10);
		$pdf->Write(0, $leave_name);
		$pdf->SetFont('Arial','B',12);
	}
	
	/*
	if ($rows['leave_type_id'] == 1)
	{
		$pdf->Ln(2);
		$pdf->SetX(27);
		$pdf->Write(0, 'X');
	}
	if ($rows['leave_type_id'] == 2)
	{
		$pdf->Ln(27);
		$pdf->SetX(27);
		$pdf->Write(0, 'X');
	}
	*/
	//$pdf->Write(0, 'City of Puerto Pricesa');
	
	
	$pdf->Ln(35);
	
	$pdf->SetXY(35, 128);
	
	$days = 'day';
	
	if ($rows['days'] > 1)
	{
		$days = 'days';
	}
	
	$pdf->Write(0, $rows['days'].' '.$days);
	
	$date_leave = $this->Helps->get_month_name($rows['month']).' '.$rows['multiple'].', '.$rows['year'];
	
	if ($rows['multiple5'] != '')
	{
		$date_leave .= ' - '.$this->Helps->get_month_name($rows['month5']).' '.$rows['multiple5'].', '.$rows['year5'];
	}
	
	$pdf->Ln(4);
	$pdf->SetX(60);
	$pdf->Write(0, $date_leave);
	
	$last_earn = $this->Leave_card->get_last_earn($rows['employee_id']);
	//$last_earn = date('F d, Y', strtotime($last_earn));
	
	if ( $last_earn != '')
	{
		$last_earn = date('F d, Y', strtotime($last_earn));
	}
	else
	{
		$last_earn = date('F d, Y');
	}
	
	
	//$vbalance =  $this->Leave_balance->get_leave_balance(1, $rows['employee_id']);
	//$sbalance =  $this->Leave_balance->get_leave_balance(2, $rows['employee_id']);
	
	$credits = $this->Leave_card->get_total_leave_credits($rows['employee_id']);

	
	$pdf->Ln(39);
	$pdf->SetX(35);
	$pdf->Write(0, $last_earn);
	
	//balances
	$pdf->Ln(18);
	$pdf->SetX(25);
	//$pdf->Write(0, $vbalance);
	$pdf->Write(0, $credits['vacation']);
	
	$pdf->SetX(54);
	//$pdf->Write(0, $sbalance);
	$pdf->Write(0, $credits['sick']);
	
	$total_leave_balance = $credits['vacation'] + $credits['sick'];
	
	$pdf->SetX(80);
	$pdf->Write(0, $total_leave_balance);
	
	
	// set font, font style, font size.
	$pdf->SetFont('Arial','B',12);
	
	$pdf->Ln(9);
	
	$pdf->SetX(136);
	
	//credits
	//vaation
	$pdf->Ln(23);
	
	$pdf->SetX(52);
	
	//$pdf->Write(0, number_format($vacation_leave, 3));
	
	//sick
	//$pdf->Ln(9);
	
	$pdf->SetX(108);
	
	//$pdf->Write(0, number_format($sick_leave, 3));
	
	//total
	//$pdf->Ln(7);
	
	$pdf->SetX(160);
	
	//$pdf->Write(0, number_format($vacation_leave + $sick_leave, 3));
	
	
	//date for the day
	$pdf->Ln(21);
	
	$pdf->SetX(67);
	
	//day
	//$pdf->Write(0, date('jS'));
	
	$pdf->SetX(104);
	
	//$pdf->Write(0, date('F'));
	
	//year
	$pdf->SetX(138);
	
	//$pdf->Write(0, date('Y'));
	
	//MR or MS. request
	$pdf->Ln(7);
	
	//$pdf->Image('white.png',10,10,-300);
	
	$pdf->SetX(32);
	
	
	$statement_certified = $this->Settings->get_selected_field('statement_certified');
	$statement_certified_position = $this->Settings->get_selected_field('statement_certified_position');
	
	$pdf->SetXY(35,205);
	$pdf->SetFillColor(255, 255, 255); 
	
	$pdf->Cell(65,5,strtoupper($statement_certified),'',0,'C',1);
	$pdf->SetXY(35,211);
	$pdf->SetFont('Arial','I',11);
	$pdf->Cell(65,5,$statement_certified_position,'',0,'C',1);
	
	// define the mapping of office code/order id to signatory values
	$sig_map = [];
	$sig_map['15|0'] = 'Meriam Dumlao';
	$sig_map['15|1'] = 'Jonathan Vega';
	// add elements to this array for other combinations ...

	// form an index consisting of the office code and order id value
	$index = $office['office_id'] .'|'. $divisions['order_id'];

	// given the index value, retrieve the signatory value
	$signature = $sig_map[$index];

	// output the data
	$pdf->SetXY(122,190);
	$pdf->Write(0, $signature);
	
	header('Cache-Control: maxage=3600'); //Adjust maxage appropriately
	
	header('Pragma: public');
	
	$pdf->Output('dtr/reports/leave-apps-'.$rows['employee_id'].'.pdf', 'I'); 
	
	//redirect(base_url().'dtr/reports/leave-apps-'.$rows['employee_id'].'.pdf', 'refresh');
	
}

Thanks a lot for you help sir. Highly appreciated.


#11

I tried what phdr said but nothing appears when I tried to output the data nothing appears for signatories.


#12

What debugging steps have you performed to find why your code isn’t working? Do the variables $office[‘office_id’] and $divisions[‘order_id’] exist at all (the office_id index is different from what you showed us at the start of this thread and there is no $divisions variable in the posted code) and do they have expected values in them? Did you create entries in the $sig_map array for the other combinations?


#13

I only tried those codes that you showed to me. I haven’t tried other values for office and division.I only tried the exact codes that you showed to me as an example but nothing appeared.


#14

The two variables I showed in the example code came from information you supplied. If these are incorrect, that’s on you. The help we provide cannot be any better then the information you supply.

The fact that you changed one of the variables, but are claiming you used the exact code I posted, means you are just wasting our time.


#15

I didn’t change any codes that you showed to me. In fact I just copy and paste the code just to be sure nothing will be changed. There’s no error when running the codes but the problem is that there’s no signatories appeared when running it. I will not waste your time in fact I’m very thankful that someone helped me.


#16

I think you do not understand what he is telling you that you need to change. All of your code like this:

	if (in_array($rows['leave_type_id'], $leave_type_ids))
	{
		$pdf->Ln(27);
		$pdf->SetX(28);
		$pdf->Write(0, 'X');
		
		$pdf->Ln(18);
		
		$pdf->SetX(32);
		
		if ( $rows['leave_type_id'] == 2 )
		{
			$leave_name = '';
		}
		
		$pdf->SetFont('Arial','B',10);
		$pdf->Write(0, $leave_name);
		$pdf->SetFont('Arial','B',12);
	}
	
	/*
	if ($rows['leave_type_id'] == 1)

That checks for the various two values can be written in just a couple lines. Just replace all of that complicated and repeating code with his version…

// define the mapping of office code/order id to signatory values
$sig_map = [];
$sig_map['15|0'] = 'Meriam Dumlao';
$sig_map['15|1'] = 'Jonathan Vega';
// add elements to this array for other combinations ...

// form an index consisting of the office code and order id value
$index = $office['office_code'] .'|'. $divisions['order_id'];

// given the index value, retrieve the signatory value
$signature = $sig_map[$index];

// output the data
$pdf->SetXY(122,190);
$pdf->Write(0,$signature);

And fill in all of your possible values for the “office_code” and “order_id” values. Then, you save a ton of duplicated code and it is much much easier to edit if you add a new office or office ID. Does this help explain what is needed?