UFPDF   D
last analyzed

Complexity

Total Complexity 102

Size/Duplication

Total Lines 453
Duplicated Lines 29.14 %

Coupling/Cohesion

Components 1
Dependencies 1
Metric Value
wmc 102
lcom 1
cbo 1
dl 132
loc 453
rs 4.8717

13 Methods

Rating   Name   Duplication   Size   Complexity  
A UFPDF() 0 5 1
A GetStringWidth() 0 11 2
D AddFont() 2 28 9
A Text() 10 10 4
A AcceptPageBreak() 0 5 1
F Cell() 32 79 26
B _puttruetypeunicode() 0 59 7
A _dounderline() 8 8 1
A _textstring() 7 7 1
A _escapetext() 7 7 1
B _putinfo() 0 15 6
D utf8_to_utf16be() 30 98 22
D utf8_to_codepoints() 36 88 21

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like UFPDF often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use UFPDF, and based on these observations, apply Extract Interface, too.

1
<?php
2
/*******************************************************************************
3
* Software: UFPDF, Unicode Free PDF generator                                  *
4
* Version:  0.1                                                                *
5
*           based on FPDF 1.52 by Olivier PLATHEY                              *
6
* Date:     2004-09-01                                                         *
7
* Author:   Steven Wittens <[email protected]>                                   *
8
* License:  GPL                                                                *
9
*                                                                              *
10
* UFPDF is a modification of FPDF to support Unicode through UTF-8.            *
11
*                                                                              *
12
*******************************************************************************/
13
14
15
class UFPDF extends FPDF
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
16
{
17
18
/*******************************************************************************
19
*                                                                              *
20
*                               Public methods                                 *
21
*                                                                              *
22
*******************************************************************************/
23
function UFPDF($orientation='P',$unit='mm',$format='A4')
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
Coding Style Best Practice introduced by
Please use __construct() instead of a PHP4-style constructor that is named after the class.
Loading history...
24
{
25
  FPDF::FPDF($orientation, $unit, $format);
0 ignored issues
show
Bug introduced by
The method FPDF() does not seem to exist on object<FPDF>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
Coding Style introduced by
PHP4 style calls to parent constructors are not allowed; use "parent::__construct()" instead
Loading history...
26
  define('FPDF_FONTPATH',dirname(__FILE__).'/font/');
27
}
28
29
function GetStringWidth($s)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
30
{
31
  //Get width of a string in the current font
32
  $s = (string)$s;
33
  $codepoints=$this->utf8_to_codepoints($s);
34
  $cw=&$this->CurrentFont['cw'];
35
  $w=0;
36
  foreach($codepoints as $cp)
37
    $w+=$cw[$cp];
38
  return $w*$this->FontSize/1000;
39
}
40
41
function AddFont($family,$style='',$file='')
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
42
{
43
  //Add a TrueType or Type1 font
44
  $family=strtolower($family);
45
  if($family=='arial')
46
    $family='helvetica';
47
  $style=strtoupper($style);
48
  if($style=='IB')
49
    $style='BI';
50
  if(isset($this->fonts[$family.$style]))
51
    $this->Error('Font already added: '.$family.' '.$style);
52 View Code Duplication
  if($file=='')
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
53
    $file=str_replace(' ','',$family).strtolower($style).'.php';
54
  if(defined('FPDF_FONTPATH'))
55
    $file=FPDF_FONTPATH.$file;
56
  include($file);
57
  if(!isset($name))
0 ignored issues
show
Bug introduced by
The variable $name seems to never exist, and therefore isset should always return false. Did you maybe rename this variable?

This check looks for calls to isset(...) or empty() on variables that are yet undefined. These calls will always produce the same result and can be removed.

This is most likely caused by the renaming of a variable or the removal of a function/method parameter.

Loading history...
58
    $this->Error('Could not include font definition file');
59
  $i=count($this->fonts)+1;
60
  $this->fonts[$family.$style]=array('i'=>$i,'type'=>$type,'name'=>$name,'desc'=>$desc,'up'=>$up,'ut'=>$ut,'cw'=>$cw,'file'=>$file,'ctg'=>$ctg);
0 ignored issues
show
Bug introduced by
The variable $type does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
Bug introduced by
The variable $name does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
Bug introduced by
The variable $desc does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
Bug introduced by
The variable $up does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
Bug introduced by
The variable $ut does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
Bug introduced by
The variable $cw does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
Bug introduced by
The variable $ctg does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
61
  if($file)
62
  {
63
    if($type=='TrueTypeUnicode')
64
      $this->FontFiles[$file]=array('length1'=>$originalsize);
0 ignored issues
show
Bug introduced by
The variable $originalsize does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
65
    else
66
      $this->FontFiles[$file]=array('length1'=>$size1,'length2'=>$size2);
0 ignored issues
show
Bug introduced by
The variable $size1 does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
Bug introduced by
The variable $size2 does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
67
  }
68
}
69
70 View Code Duplication
function Text($x,$y,$txt)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
71
{
72
  //Output a string
73
  $s=sprintf('BT %.2f %.2f Td %s Tj ET',$x*$this->k,($this->h-$y)*$this->k,$this->_escapetext($txt));
74
  if($this->underline and $txt!='')
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as and instead of && is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
75
    $s.=' '.$this->_dounderline($x,$y,$this->GetStringWidth($txt),$txt);
76
  if($this->ColorFlag)
77
    $s='q '.$this->TextColor.' '.$s.' Q';
78
  $this->_out($s);
79
}
80
81
function AcceptPageBreak()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
82
{
83
  //Accept automatic page break or not
84
  return $this->AutoPageBreak;
85
}
86
87
function Cell($w,$h=0,$txt='',$border=0,$ln=0,$align='',$fill=0,$link='')
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
88
{
89
  //Output a cell
90
  $k=$this->k;
91
  if($this->y+$h>$this->PageBreakTrigger and !$this->InFooter and $this->AcceptPageBreak())
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as and instead of && is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
92
  {
93
    //Automatic page break
94
    $x=$this->x;
95
    $ws=$this->ws;
96
    if($ws>0)
97
    {
98
      $this->ws=0;
99
      $this->_out('0 Tw');
100
    }
101
    $this->AddPage($this->CurOrientation);
102
    $this->x=$x;
103 View Code Duplication
    if($ws>0)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
104
    {
105
      $this->ws=$ws;
106
      $this->_out(sprintf('%.3f Tw',$ws*$k));
107
    }
108
  }
109
  if($w==0)
110
    $w=$this->w-$this->rMargin-$this->x;
111
  $s='';
112
  if($fill==1 or $border==1)
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as or instead of || is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
113
  {
114
    if($fill==1)
115
      $op=($border==1) ? 'B' : 'f';
116
    else
117
      $op='S';
118
    $s=sprintf('%.2f %.2f %.2f %.2f re %s ',$this->x*$k,($this->h-$this->y)*$k,$w*$k,-$h*$k,$op);
119
  }
120
  if(is_string($border))
121
  {
122
    $x=$this->x;
123
    $y=$this->y;
124 View Code Duplication
    if(is_int(strpos($border,'L')))
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
125
      $s.=sprintf('%.2f %.2f m %.2f %.2f l S ',$x*$k,($this->h-$y)*$k,$x*$k,($this->h-($y+$h))*$k);
126 View Code Duplication
    if(is_int(strpos($border,'T')))
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
127
      $s.=sprintf('%.2f %.2f m %.2f %.2f l S ',$x*$k,($this->h-$y)*$k,($x+$w)*$k,($this->h-$y)*$k);
128 View Code Duplication
    if(is_int(strpos($border,'R')))
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
129
      $s.=sprintf('%.2f %.2f m %.2f %.2f l S ',($x+$w)*$k,($this->h-$y)*$k,($x+$w)*$k,($this->h-($y+$h))*$k);
130 View Code Duplication
    if(is_int(strpos($border,'B')))
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
131
      $s.=sprintf('%.2f %.2f m %.2f %.2f l S ',$x*$k,($this->h-($y+$h))*$k,($x+$w)*$k,($this->h-($y+$h))*$k);
132
  }
133
  if($txt!='')
134
  {
135
    $width = $this->GetStringWidth($txt);
136 View Code Duplication
    if($align=='R')
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
137
      $dx=$w-$this->cMargin-$width;
138
    elseif($align=='C')
139
      $dx=($w-$width)/2;
140
    else
141
      $dx=$this->cMargin;
142
    if($this->ColorFlag)
143
      $s.='q '.$this->TextColor.' ';
144
    $txtstring=$this->_escapetext($txt);
145
    $s.=sprintf('BT %.2f %.2f Td %s Tj ET',($this->x+$dx)*$k,($this->h-($this->y+.5*$h+.3*$this->FontSize))*$k,$txtstring);
146 View Code Duplication
    if($this->underline)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
147
      $s.=' '.$this->_dounderline($this->x+$dx,$this->y+.5*$h+.3*$this->FontSize,$width,$txt);
148
    if($this->ColorFlag)
149
      $s.=' Q';
150 View Code Duplication
    if($link)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
151
      $this->Link($this->x+$dx,$this->y+.5*$h-.5*$this->FontSize,$width,$this->FontSize,$link);
152
  }
153
  if($s)
154
    $this->_out($s);
155
  $this->lasth=$h;
156 View Code Duplication
  if($ln>0)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
157
  {
158
    //Go to next line
159
    $this->y+=$h;
160
    if($ln==1)
161
      $this->x=$this->lMargin;
162
  }
163
  else
164
    $this->x+=$w;
165
}
166
167
/*******************************************************************************
168
*                                                                              *
169
*                              Protected methods                               *
170
*                                                                              *
171
*******************************************************************************/
172
173
function _puttruetypeunicode($font) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
174
  //Type0 Font
175
  $this->_newobj();
176
  $this->_out('<</Type /Font');
177
  $this->_out('/Subtype /Type0');
178
  $this->_out('/BaseFont /'. $font['name'] .'-UCS');
179
  $this->_out('/Encoding /Identity-H');
180
  $this->_out('/DescendantFonts ['. ($this->n + 1) .' 0 R]');
181
  $this->_out('>>');
182
  $this->_out('endobj');
183
184
  //CIDFont
185
  $this->_newobj();
186
  $this->_out('<</Type /Font');
187
  $this->_out('/Subtype /CIDFontType2');
188
  $this->_out('/BaseFont /'. $font['name']);
189
  $this->_out('/CIDSystemInfo <</Registry (Adobe) /Ordering (UCS) /Supplement 0>>');
190
  $this->_out('/FontDescriptor '. ($this->n + 1) .' 0 R');
191
  $c = 0;
0 ignored issues
show
Unused Code introduced by
$c is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
192
  foreach ($font['cw'] as $i => $w) {
193
    $widths .= $i .' ['. $w.'] ';
0 ignored issues
show
Bug introduced by
The variable $widths does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
194
  }
195
  $this->_out('/W ['. $widths .']');
196
  $this->_out('/CIDToGIDMap '. ($this->n + 2) .' 0 R');
197
  $this->_out('>>');
198
  $this->_out('endobj');
199
200
  //Font descriptor
201
  $this->_newobj();
202
  $this->_out('<</Type /FontDescriptor');
203
  $this->_out('/FontName /'.$font['name']);
204
  foreach ($font['desc'] as $k => $v) {
205
    $s .= ' /'. $k .' '. $v;
0 ignored issues
show
Bug introduced by
The variable $s does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
206
  }
207
  if ($font['file']) {
208
		$s .= ' /FontFile2 '. $this->FontFiles[$font['file']]['n'] .' 0 R';
209
  }
210
  $this->_out($s);
211
  $this->_out('>>');
212
  $this->_out('endobj');
213
214
  //Embed CIDToGIDMap
215
  $this->_newobj();
216
  if(defined('FPDF_FONTPATH'))
217
    $file=FPDF_FONTPATH.$font['ctg'];
218
  else
219
    $file=$font['ctg'];
220
  $size=filesize($file);
221
  if(!$size)
222
    $this->Error('Font file not found');
223
  $this->_out('<</Length '.$size);
224
	if(substr($file,-2) == '.z')
225
    $this->_out('/Filter /FlateDecode');
226
  $this->_out('>>');
227
  $f = fopen($file,'rb');
228
  $this->_putstream(fread($f,$size));
229
  fclose($f);
230
  $this->_out('endobj');
231
}
232
233 View Code Duplication
function _dounderline($x,$y,$width,$txt)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
234
{
235
  //Underline text
236
  $up=$this->CurrentFont['up'];
237
  $ut=$this->CurrentFont['ut'];
238
  $w=$width+$this->ws*substr_count($txt,' ');
239
  return sprintf('%.2f %.2f %.2f %.2f re f',$x*$this->k,($this->h-($y-$up/1000*$this->FontSize))*$this->k,$w*$this->k,-$ut/1000*$this->FontSizePt);
240
}
241
242 View Code Duplication
function _textstring($s)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
243
{
244
  //Convert to UTF-16BE
245
  $s = $this->utf8_to_utf16be($s);
246
  //Escape necessary characters
247
  return '('. strtr($s, array(')' => '\\)', '(' => '\\(', '\\' => '\\\\')) .')';
248
}
249
250 View Code Duplication
function _escapetext($s)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
251
{
252
  //Convert to UTF-16BE
253
  $s = $this->utf8_to_utf16be($s, false);
254
  //Escape necessary characters
255
  return '('. strtr($s, array(')' => '\\)', '(' => '\\(', '\\' => '\\\\')) .')';
256
}
257
258
function _putinfo()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
259
{
260
	$this->_out('/Producer '.$this->_textstring('UFPDF '. UFPDF_VERSION));
261
	if(!empty($this->title))
262
		$this->_out('/Title '.$this->_textstring($this->title));
0 ignored issues
show
Bug introduced by
The property title does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
263
	if(!empty($this->subject))
264
		$this->_out('/Subject '.$this->_textstring($this->subject));
0 ignored issues
show
Bug introduced by
The property subject does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
265
	if(!empty($this->author))
266
		$this->_out('/Author '.$this->_textstring($this->author));
0 ignored issues
show
Bug introduced by
The property author does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
267
	if(!empty($this->keywords))
268
		$this->_out('/Keywords '.$this->_textstring($this->keywords));
0 ignored issues
show
Bug introduced by
The property keywords does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
269
	if(!empty($this->creator))
270
		$this->_out('/Creator '.$this->_textstring($this->creator));
0 ignored issues
show
Bug introduced by
The property creator does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
271
	$this->_out('/CreationDate '.$this->_textstring('D:'.date('YmdHis')));
272
}
273
274
// UTF-8 to UTF-16BE conversion.
275
// Correctly handles all illegal UTF-8 sequences.
276
function utf8_to_utf16be(&$txt, $bom = true) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
277
  $l = strlen($txt);
278
  $out = $bom ? "\xFE\xFF" : '';
279
  for ($i = 0; $i < $l; ++$i) {
280
    $c = ord($txt{$i});
281
    // ASCII
282
    if ($c < 0x80) {
283
      $out .= "\x00". $txt{$i};
284
    }
285
    // Lost continuation byte
286
    else if ($c < 0xC0) {
287
      $out .= "\xFF\xFD";
288
      continue;
289
    }
290
    // Multibyte sequence leading byte
291
    else {
292 View Code Duplication
      if ($c < 0xE0) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
293
        $s = 2;
294
      }
295
      else if ($c < 0xF0) {
296
        $s = 3;
297
      }
298
      else if ($c < 0xF8) {
299
        $s = 4;
300
      }
301
      // 5/6 byte sequences not possible for Unicode.
302
      else {
303
        $out .= "\xFF\xFD";
304
        while (ord($txt{$i + 1}) >= 0x80 && ord($txt{$i + 1}) < 0xC0) { ++$i; }
305
        continue;
306
      }
307
308
      $q = array($c);
309
      // Fetch rest of sequence
310 View Code Duplication
      while (ord($txt{$i + 1}) >= 0x80 && ord($txt{$i + 1}) < 0xC0) { ++$i; $q[] = ord($txt{$i}); }
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
311
312
      // Check length
313
      if (count($q) != $s) {
314
        $out .= "\xFF\xFD";
315
        continue;
316
      }
317
318
      switch ($s) {
319
        case 2:
320
          $cp = (($q[0] ^ 0xC0) << 6) | ($q[1] ^ 0x80);
321
          // Overlong sequence
322 View Code Duplication
          if ($cp < 0x80) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
323
            $out .= "\xFF\xFD";
324
          }
325
          else {
326
            $out .= chr($cp >> 8);
327
            $out .= chr($cp & 0xFF);
328
          }
329
          continue;
330
331
        case 3:
332
          $cp = (($q[0] ^ 0xE0) << 12) | (($q[1] ^ 0x80) << 6) | ($q[2] ^ 0x80);
333
          // Overlong sequence
334
          if ($cp < 0x800) {
335
            $out .= "\xFF\xFD";
336
          }
337
          // Check for UTF-8 encoded surrogates (caused by a bad UTF-8 encoder)
338 View Code Duplication
          else if ($c > 0xD800 && $c < 0xDFFF) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
339
            $out .= "\xFF\xFD";
340
          }
341
          else {
342
            $out .= chr($cp >> 8);
343
            $out .= chr($cp & 0xFF);
344
          }
345
          continue;
346
347
        case 4:
348
          $cp = (($q[0] ^ 0xF0) << 18) | (($q[1] ^ 0x80) << 12) | (($q[2] ^ 0x80) << 6) | ($q[3] ^ 0x80);
349
          // Overlong sequence
350
          if ($cp < 0x10000) {
351
            $out .= "\xFF\xFD";
352
          }
353
          // Outside of the Unicode range
354
          else if ($cp >= 0x10FFFF) {
355
            $out .= "\xFF\xFD";
356
          }
357
          else {
358
            // Use surrogates
359
            $cp -= 0x10000;
360
            $s1 = 0xD800 | ($cp >> 10);
361
            $s2 = 0xDC00 | ($cp & 0x3FF);
362
363
            $out .= chr($s1 >> 8);
364
            $out .= chr($s1 & 0xFF);
365
            $out .= chr($s2 >> 8);
366
            $out .= chr($s2 & 0xFF);
367
          }
368
          continue;
369
      }
370
    }
371
  }
372
  return $out;
373
}
374
375
// UTF-8 to codepoint array conversion.
376
// Correctly handles all illegal UTF-8 sequences.
377
function utf8_to_codepoints(&$txt) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
378
  $l = strlen($txt);
379
  $out = array();
380
  for ($i = 0; $i < $l; ++$i) {
381
    $c = ord($txt{$i});
382
    // ASCII
383
    if ($c < 0x80) {
384
      $out[] = ord($txt{$i});
385
    }
386
    // Lost continuation byte
387
    else if ($c < 0xC0) {
388
      $out[] = 0xFFFD;
389
      continue;
390
    }
391
    // Multibyte sequence leading byte
392
    else {
393 View Code Duplication
      if ($c < 0xE0) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
394
        $s = 2;
395
      }
396
      else if ($c < 0xF0) {
397
        $s = 3;
398
      }
399
      else if ($c < 0xF8) {
400
        $s = 4;
401
      }
402
      // 5/6 byte sequences not possible for Unicode.
403
      else {
404
        $out[] = 0xFFFD;
405
        while (ord($txt{$i + 1}) >= 0x80 && ord($txt{$i + 1}) < 0xC0) { ++$i; }
406
        continue;
407
      }
408
409
      $q = array($c);
410
      // Fetch rest of sequence
411 View Code Duplication
      while (ord($txt{$i + 1}) >= 0x80 && ord($txt{$i + 1}) < 0xC0) { ++$i; $q[] = ord($txt{$i}); }
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
412
413
      // Check length
414
      if (count($q) != $s) {
415
        $out[] = 0xFFFD;
416
        continue;
417
      }
418
419
      switch ($s) {
420
        case 2:
421
          $cp = (($q[0] ^ 0xC0) << 6) | ($q[1] ^ 0x80);
422
          // Overlong sequence
423
          if ($cp < 0x80) {
424
            $out[] = 0xFFFD;
425
          }
426
          else {
427
            $out[] = $cp;
428
          }
429
          continue;
430
431
        case 3:
432
          $cp = (($q[0] ^ 0xE0) << 12) | (($q[1] ^ 0x80) << 6) | ($q[2] ^ 0x80);
433
          // Overlong sequence
434 View Code Duplication
          if ($cp < 0x800) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
435
            $out[] = 0xFFFD;
436
          }
437
          // Check for UTF-8 encoded surrogates (caused by a bad UTF-8 encoder)
438
          else if ($c > 0xD800 && $c < 0xDFFF) {
439
            $out[] = 0xFFFD;
440
          }
441
          else {
442
            $out[] = $cp;
443
          }
444
          continue;
445
446
        case 4:
447
          $cp = (($q[0] ^ 0xF0) << 18) | (($q[1] ^ 0x80) << 12) | (($q[2] ^ 0x80) << 6) | ($q[3] ^ 0x80);
448
          // Overlong sequence
449 View Code Duplication
          if ($cp < 0x10000) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
450
            $out[] = 0xFFFD;
451
          }
452
          // Outside of the Unicode range
453
          else if ($cp >= 0x10FFFF) {
454
            $out[] = 0xFFFD;
455
          }
456
          else {
457
            $out[] = $cp;
458
          }
459
          continue;
460
      }
461
    }
462
  }
463
  return $out;
464
}
465
466
//End of class
467
}
468
?>
0 ignored issues
show
Best Practice introduced by
It is not recommended to use PHP's closing tag ?> in files other than templates.

Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore.

A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever.

Loading history...
469