1<?php 2/** 3 * Zend Framework (http://framework.zend.com/) 4 * 5 * @link http://github.com/zendframework/zf2 for the canonical source repository 6 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 7 * @license http://framework.zend.com/license/new-bsd New BSD License 8 */ 9 10namespace Zend\Console; 11 12/** 13 * A static, utility class for interacting with Console environment. 14 * Declared abstract to prevent from instantiating. 15 */ 16abstract class Console 17{ 18 /** 19 * @var Adapter\AdapterInterface 20 */ 21 protected static $instance; 22 23 /** 24 * Allow overriding whether or not we're in a console env. If set, and 25 * boolean, returns that value from isConsole(). 26 * @var bool 27 */ 28 protected static $isConsole; 29 30 /** 31 * Create and return Adapter\AdapterInterface instance. 32 * 33 * @param null|string $forceAdapter Optional adapter class name. Can be absolute namespace or class name 34 * relative to Zend\Console\Adapter\. If not provided, a best matching 35 * adapter will be automatically selected. 36 * @param null|string $forceCharset optional charset name can be absolute namespace or class name relative to 37 * Zend\Console\Charset\. If not provided, charset will be detected 38 * automatically. 39 * @throws Exception\InvalidArgumentException 40 * @throws Exception\RuntimeException 41 * @return Adapter\AdapterInterface 42 */ 43 public static function getInstance($forceAdapter = null, $forceCharset = null) 44 { 45 if (static::$instance instanceof Adapter\AdapterInterface) { 46 return static::$instance; 47 } 48 49 // Create instance 50 51 if ($forceAdapter !== null) { 52 // Use the supplied adapter class 53 if (substr($forceAdapter, 0, 1) == '\\') { 54 $className = $forceAdapter; 55 } elseif (stristr($forceAdapter, '\\')) { 56 $className = __NAMESPACE__ . '\\' . ltrim($forceAdapter, '\\'); 57 } else { 58 $className = __NAMESPACE__ . '\\Adapter\\' . $forceAdapter; 59 } 60 61 if (!class_exists($className)) { 62 throw new Exception\InvalidArgumentException(sprintf( 63 'Cannot find Console adapter class "%s"', 64 $className 65 )); 66 } 67 } else { 68 // Try to detect best instance for console 69 $className = static::detectBestAdapter(); 70 71 // Check if we were able to detect console adapter 72 if (!$className) { 73 throw new Exception\RuntimeException('Cannot create Console adapter - am I running in a console?'); 74 } 75 } 76 77 // Create adapter instance 78 static::$instance = new $className(); 79 80 // Try to use the supplied charset class 81 if ($forceCharset !== null) { 82 if (substr($forceCharset, 0, 1) == '\\') { 83 $className = $forceCharset; 84 } elseif (stristr($forceAdapter, '\\')) { 85 $className = __NAMESPACE__ . '\\' . ltrim($forceCharset, '\\'); 86 } else { 87 $className = __NAMESPACE__ . '\\Charset\\' . $forceCharset; 88 } 89 90 if (!class_exists($className)) { 91 throw new Exception\InvalidArgumentException(sprintf( 92 'Cannot find Charset class "%s"', 93 $className 94 )); 95 } 96 97 // Set adapter charset 98 static::$instance->setCharset(new $className()); 99 } 100 101 return static::$instance; 102 } 103 104 /** 105 * Reset the console instance 106 */ 107 public static function resetInstance() 108 { 109 static::$instance = null; 110 } 111 112 /** 113 * Check if currently running under MS Windows 114 * 115 * @see http://stackoverflow.com/questions/738823/possible-values-for-php-os 116 * @return bool 117 */ 118 public static function isWindows() 119 { 120 return 121 (defined('PHP_OS') && (substr_compare(PHP_OS, 'win', 0, 3, true) === 0)) || 122 (getenv('OS') != false && substr_compare(getenv('OS'), 'windows', 0, 7, true)) 123 ; 124 } 125 126 /** 127 * Check if running under MS Windows Ansicon 128 * 129 * @return bool 130 */ 131 public static function isAnsicon() 132 { 133 return getenv('ANSICON') !== false; 134 } 135 136 /** 137 * Check if running in a console environment (CLI) 138 * 139 * By default, returns value of PHP_SAPI global constant. If $isConsole is 140 * set, and a boolean value, that value will be returned. 141 * 142 * @return bool 143 */ 144 public static function isConsole() 145 { 146 if (null === static::$isConsole) { 147 static::$isConsole = (PHP_SAPI == 'cli'); 148 } 149 return static::$isConsole; 150 } 151 152 /** 153 * Override the "is console environment" flag 154 * 155 * @param null|bool $flag 156 */ 157 public static function overrideIsConsole($flag) 158 { 159 if (null != $flag) { 160 $flag = (bool) $flag; 161 } 162 static::$isConsole = $flag; 163 } 164 165 /** 166 * Try to detect best matching adapter 167 * @return string|null 168 */ 169 public static function detectBestAdapter() 170 { 171 // Check if we are in a console environment 172 if (!static::isConsole()) { 173 return; 174 } 175 176 // Check if we're on windows 177 if (static::isWindows()) { 178 if (static::isAnsicon()) { 179 $className = __NAMESPACE__ . '\Adapter\WindowsAnsicon'; 180 } else { 181 $className = __NAMESPACE__ . '\Adapter\Windows'; 182 } 183 184 return $className; 185 } 186 187 // Default is a Posix console 188 $className = __NAMESPACE__ . '\Adapter\Posix'; 189 return $className; 190 } 191 192 /** 193 * Pass-thru static call to current AdapterInterface instance. 194 * 195 * @param $funcName 196 * @param $arguments 197 * @return mixed 198 */ 199 public static function __callStatic($funcName, $arguments) 200 { 201 $instance = static::getInstance(); 202 return call_user_func_array(array($instance, $funcName), $arguments); 203 } 204} 205