1<?php 2/* 3 * This file is part of PHPUnit. 4 * 5 * (c) Sebastian Bergmann <sebastian@phpunit.de> 6 * 7 * For the full copyright and license information, please view the LICENSE 8 * file that was distributed with this source code. 9 */ 10 11/** 12 * Utility class that can print to STDOUT or write to a file. 13 */ 14class PHPUnit_Util_Printer 15{ 16 /** 17 * If true, flush output after every write. 18 * 19 * @var bool 20 */ 21 protected $autoFlush = false; 22 23 /** 24 * @var resource 25 */ 26 protected $out; 27 28 /** 29 * @var string 30 */ 31 protected $outTarget; 32 33 /** 34 * Constructor. 35 * 36 * @param mixed $out 37 * 38 * @throws PHPUnit_Framework_Exception 39 */ 40 public function __construct($out = null) 41 { 42 if ($out !== null) { 43 if (is_string($out)) { 44 if (strpos($out, 'socket://') === 0) { 45 $out = explode(':', str_replace('socket://', '', $out)); 46 47 if (count($out) != 2) { 48 throw new PHPUnit_Framework_Exception; 49 } 50 51 $this->out = fsockopen($out[0], $out[1]); 52 } else { 53 if (strpos($out, 'php://') === false && 54 !is_dir(dirname($out))) { 55 mkdir(dirname($out), 0777, true); 56 } 57 58 $this->out = fopen($out, 'wt'); 59 } 60 61 $this->outTarget = $out; 62 } else { 63 $this->out = $out; 64 } 65 } 66 } 67 68 /** 69 * Flush buffer and close output if it's not to a PHP stream 70 */ 71 public function flush() 72 { 73 if ($this->out && strncmp($this->outTarget, 'php://', 6) !== 0) { 74 fclose($this->out); 75 } 76 } 77 78 /** 79 * Performs a safe, incremental flush. 80 * 81 * Do not confuse this function with the flush() function of this class, 82 * since the flush() function may close the file being written to, rendering 83 * the current object no longer usable. 84 */ 85 public function incrementalFlush() 86 { 87 if ($this->out) { 88 fflush($this->out); 89 } else { 90 flush(); 91 } 92 } 93 94 /** 95 * @param string $buffer 96 */ 97 public function write($buffer) 98 { 99 if ($this->out) { 100 fwrite($this->out, $buffer); 101 102 if ($this->autoFlush) { 103 $this->incrementalFlush(); 104 } 105 } else { 106 if (PHP_SAPI != 'cli' && PHP_SAPI != 'phpdbg') { 107 $buffer = htmlspecialchars($buffer, ENT_SUBSTITUTE); 108 } 109 110 print $buffer; 111 112 if ($this->autoFlush) { 113 $this->incrementalFlush(); 114 } 115 } 116 } 117 118 /** 119 * Check auto-flush mode. 120 * 121 * @return bool 122 */ 123 public function getAutoFlush() 124 { 125 return $this->autoFlush; 126 } 127 128 /** 129 * Set auto-flushing mode. 130 * 131 * If set, *incremental* flushes will be done after each write. This should 132 * not be confused with the different effects of this class' flush() method. 133 * 134 * @param bool $autoFlush 135 */ 136 public function setAutoFlush($autoFlush) 137 { 138 if (is_bool($autoFlush)) { 139 $this->autoFlush = $autoFlush; 140 } else { 141 throw PHPUnit_Util_InvalidArgumentHelper::factory(1, 'boolean'); 142 } 143 } 144} 145