Completed
Push — master ( 221921...32345e )
by Bhanu
58:02
created

dompdf.php ➔ getoptions()   C

Complexity

Conditions 18
Paths 18

Size

Total Lines 77
Code Lines 59

Duplication

Lines 30
Ratio 38.96 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 18
eloc 59
nc 18
nop 0
dl 30
loc 77
rs 5.1779
c 1
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Command line utility to use dompdf.
4
 * Can also be used with HTTP GET parameters
5
 * 
6
 * @package dompdf
7
 * @link    http://dompdf.github.com/
8
 * @author  Benj Carson <[email protected]>
9
 * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
10
 */
11
12
/**
13
 * Display command line usage
14
 */
15
function dompdf_usage() {
16
  $default_paper_size = DOMPDF_DEFAULT_PAPER_SIZE;
17
  
18
  echo <<<EOD
19
  
20
Usage: {$_SERVER["argv"][0]} [options] html_file
21
22
html_file can be a filename, a url if fopen_wrappers are enabled, or the '-' character to read from standard input.
23
24
Options:
25
 -h             Show this message
26
 -l             List available paper sizes
27
 -p size        Paper size; something like 'letter', 'A4', 'legal', etc.  
28
                  The default is '$default_paper_size'
29
 -o orientation Either 'portrait' or 'landscape'.  Default is 'portrait'
30
 -b path        Set the 'document root' of the html_file.  
31
                  Relative urls (for stylesheets) are resolved using this directory.  
32
                  Default is the directory of html_file.
33
 -f file        The output filename.  Default is the input [html_file].pdf
34
 -v             Verbose: display html parsing warnings and file not found errors.
35
 -d             Very verbose: display oodles of debugging output: every frame 
36
                  in the tree printed to stdout.
37
 -t             Comma separated list of debugging types (page-break,reflow,split)
38
 
39
EOD;
40
exit;
41
}
42
43
/**
44
 * Parses command line options
45
 * 
46
 * @return array The command line options
47
 */
48
function getoptions() {
49
50
  $opts = array();
51
52
  if ( $_SERVER["argc"] == 1 )
53
    return $opts;
54
55
  $i = 1;
56
  while ($i < $_SERVER["argc"]) {
57
58
    switch ($_SERVER["argv"][$i]) {
59
60
    case "--help":
61
    case "-h":
62
      $opts["h"] = true;
63
      $i++;
64
      break;
65
66
    case "-l":
67
      $opts["l"] = true;
68
      $i++;
69
      break;
70
71 View Code Duplication
    case "-p":
72
      if ( !isset($_SERVER["argv"][$i+1]) )
73
        die("-p switch requires a size parameter\n");
74
      $opts["p"] = $_SERVER["argv"][$i+1];
75
      $i += 2;
76
      break;
77
78 View Code Duplication
    case "-o":
79
      if ( !isset($_SERVER["argv"][$i+1]) )
80
        die("-o switch requires an orientation parameter\n");
81
      $opts["o"] = $_SERVER["argv"][$i+1];
82
      $i += 2;
83
      break;
84
85 View Code Duplication
    case "-b":
86
      if ( !isset($_SERVER["argv"][$i+1]) )
87
        die("-b switch requires a path parameter\n");
88
      $opts["b"] = $_SERVER["argv"][$i+1];
89
      $i += 2;
90
      break;
91
92 View Code Duplication
    case "-f":
93
      if ( !isset($_SERVER["argv"][$i+1]) )
94
        die("-f switch requires a filename parameter\n");
95
      $opts["f"] = $_SERVER["argv"][$i+1];
96
      $i += 2;
97
      break;
98
99
    case "-v":
100
      $opts["v"] = true;
101
      $i++;
102
      break;
103
104
    case "-d":
105
      $opts["d"] = true;
106
      $i++;
107
      break;
108
109 View Code Duplication
    case "-t":
110
      if ( !isset($_SERVER['argv'][$i + 1]) )
111
        die("-t switch requires a comma separated list of types\n");
112
      $opts["t"] = $_SERVER['argv'][$i+1];
113
      $i += 2;
114
      break;
115
116
   default:
117
      $opts["filename"] = $_SERVER["argv"][$i];
118
      $i++;
119
      break;
120
    }
121
122
  }
123
  return $opts;
124
}
125
126
require_once("dompdf_config.inc.php");
127
global $_dompdf_show_warnings, $_dompdf_debug, $_DOMPDF_DEBUG_TYPES;
128
129
$sapi = php_sapi_name();
130
$options = array();
131
132
$dompdf = new DOMPDF();
133
134
switch ( $sapi ) {
135
136
 case "cli":
137
138
  $opts = getoptions();
139
140
  if ( isset($opts["h"]) || (!isset($opts["filename"]) && !isset($opts["l"])) ) {
141
    dompdf_usage();
142
    exit;
143
  }
144
145
  if ( isset($opts["l"]) ) {
146
    echo "\nUnderstood paper sizes:\n";
147
148
    foreach (array_keys(CPDF_Adapter::$PAPER_SIZES) as $size)
0 ignored issues
show
Bug introduced by
The property PAPER_SIZES cannot be accessed from this context as it is declared private in class CPDF_Adapter.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
149
      echo "  " . mb_strtoupper($size) . "\n";
150
    exit;
151
  }
152
  $file = $opts["filename"];
153
154
  if ( isset($opts["p"]) )
155
    $paper = $opts["p"];
156
  else
157
    $paper = DOMPDF_DEFAULT_PAPER_SIZE;
158
159
  if ( isset($opts["o"]) )
160
    $orientation = $opts["o"];
161
  else
162
    $orientation = "portrait";
163
164
  if ( isset($opts["b"]) )
165
    $base_path = $opts["b"];
166
167
  if ( isset($opts["f"]) )
168
    $outfile = $opts["f"];
169
  else {
170
    if ( $file === "-" )
171
      $outfile = "dompdf_out.pdf";
172
    else
173
      $outfile = str_ireplace(array(".html", ".htm"), "", $file) . ".pdf";
174
  }
175
176
  if ( isset($opts["v"]) )
177
    $_dompdf_show_warnings = true;
178
179
  if ( isset($opts["d"]) ) {
180
    $_dompdf_show_warnings = true;
181
    $_dompdf_debug = true;
182
  }
183
184
  if ( isset($opts['t']) ) {
185
    $arr = split(',',$opts['t']);
186
    $types = array();
187
    foreach ($arr as $type)
188
      $types[ trim($type) ] = 1;
189
    $_DOMPDF_DEBUG_TYPES = $types;
190
  }
191
  
192
  $save_file = true;
193
194
  break;
195
196
 default:
197
198
  $dompdf->set_option('enable_php', false);
199
  
200
  if ( isset($_GET["input_file"]) )
201
    $file = rawurldecode($_GET["input_file"]);
202
  else
203
    throw new DOMPDF_Exception("An input file is required (i.e. input_file _GET variable).");
204
  
205
  if ( isset($_GET["paper"]) )
206
    $paper = rawurldecode($_GET["paper"]);
207
  else
208
    $paper = DOMPDF_DEFAULT_PAPER_SIZE;
209
  
210
  if ( isset($_GET["orientation"]) )
211
    $orientation = rawurldecode($_GET["orientation"]);
212
  else
213
    $orientation = "portrait";
214
  
215
  if ( isset($_GET["base_path"]) ) {
216
    $base_path = rawurldecode($_GET["base_path"]);
217
    $file = $base_path . $file; # Set the input file
218
  }  
219
  
220
  if ( isset($_GET["options"]) ) {
221
    $options = $_GET["options"];
222
  }
223
  
224
  $file_parts = explode_url($file);
225
  
226
  $outfile = "dompdf_out.pdf"; # Don't allow them to set the output file
227
  $save_file = false; # Don't save the file
228
  
229
  break;
230
}
231
232
if ( $file === "-" ) {
233
  $str = "";
234
  while ( !feof(STDIN) )
235
    $str .= fread(STDIN, 4096);
236
237
  $dompdf->load_html($str);
238
239
} else
240
  $dompdf->load_html_file($file);
241
242
if ( isset($base_path) ) {
243
  $dompdf->set_base_path($base_path);
244
}
245
246
$dompdf->set_paper($paper, $orientation);
247
248
$dompdf->render();
249
250
if ( $_dompdf_show_warnings ) {
251
  global $_dompdf_warnings;
252
  foreach ($_dompdf_warnings as $msg)
253
    echo $msg . "\n";
254
  echo $dompdf->get_canvas()->get_cpdf()->messages;
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Canvas as the method get_cpdf() does only exist in the following implementations of said interface: CPDF_Adapter, CPDF_Adapter, Cached_PDF_Decorator, Cached_PDF_Decorator.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
255
  flush();
256
}
257
258
if ( $save_file ) {
259
//   if ( !is_writable($outfile) )
260
//     throw new DOMPDF_Exception("'$outfile' is not writable.");
261
  if ( strtolower(DOMPDF_PDF_BACKEND) === "gd" )
262
    $outfile = str_replace(".pdf", ".png", $outfile);
263
264
  list($proto, $host, $path, $file) = explode_url($outfile);
265
  if ( $proto != "" ) // i.e. not file://
266
    $outfile = $file; // just save it locally, FIXME? could save it like wget: ./host/basepath/file
267
268
  $outfile = realpath(dirname($outfile)) . DIRECTORY_SEPARATOR . basename($outfile);
269
270
  if ( strpos($outfile, DOMPDF_CHROOT) !== 0 )
271
    throw new DOMPDF_Exception("Permission denied.");
272
273
  file_put_contents($outfile, $dompdf->output( array("compress" => 0) ));
274
  exit(0);
275
}
276
277
if ( !headers_sent() ) {
278
  $dompdf->stream($outfile, $options);
279
}
280