1<?php 2/** 3 * Matomo - free/libre analytics platform 4 * 5 * @link https://matomo.org 6 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later 7 * 8 */ 9namespace Piwik; 10 11/** 12 * Contains helper methods that can be used to get information regarding the 13 * server, its settings and currently used PHP settings. 14 * 15 */ 16class SettingsServer 17{ 18 /** 19 * Returns true if the current script execution was triggered by the cron archiving script. 20 * 21 * Helpful for error handling: directly throw error without HTML (eg. when DB is down). 22 * 23 * @return bool 24 * @api 25 */ 26 public static function isArchivePhpTriggered() 27 { 28 return !empty($_GET['trigger']) 29 && $_GET['trigger'] == 'archivephp' 30 && Piwik::hasUserSuperUserAccess(); 31 } 32 33 /** 34 * Returns true if the current request is a Tracker request. 35 * 36 * @return bool true if the current request is a Tracking API Request (ie. piwik.php) 37 */ 38 public static function isTrackerApiRequest() 39 { 40 return !empty($GLOBALS['PIWIK_TRACKER_MODE']); 41 } 42 43 /** 44 * Mark the current request as a Tracker API request 45 */ 46 public static function setIsTrackerApiRequest() 47 { 48 $GLOBALS['PIWIK_TRACKER_MODE'] = true; 49 } 50 51 /** 52 * Set the current request is not a tracker API request 53 */ 54 public static function setIsNotTrackerApiRequest() 55 { 56 $GLOBALS['PIWIK_TRACKER_MODE'] = false; 57 } 58 59 /** 60 * Returns true if Matomo is running within Matomo for WordPress. 61 * 62 * @return bool true if Matomo is running in WordPress, false if Matomo is running as part of On-Premise 63 * @api 64 */ 65 public static function isMatomoForWordPress() 66 { 67 return defined( 'ABSPATH') && function_exists('\add_action'); 68 } 69 70 /** 71 * Returns `true` if running on Microsoft IIS 7 (or above), `false` if otherwise. 72 * 73 * @return bool 74 * @api 75 */ 76 public static function isIIS() 77 { 78 $iis = isset($_SERVER['SERVER_SOFTWARE']) && 79 preg_match('/^Microsoft-IIS\/(.+)/', $_SERVER['SERVER_SOFTWARE'], $matches) && 80 version_compare($matches[1], '7') >= 0; 81 82 return $iis; 83 } 84 85 /** 86 * Returns `true` if running on a Windows operating system, `false` if otherwise. 87 * 88 * @since 0.6.5 89 * @return bool 90 * @api 91 */ 92 public static function isWindows() 93 { 94 if (PHP_OS_FAMILY == "Unknown") { 95 return DIRECTORY_SEPARATOR === '\\'; 96 } 97 return PHP_OS_FAMILY === "Windows"; 98 } 99 100 /** 101 * Returns `true` if this PHP version/build supports timezone manipulation 102 * (e.g., php >= 5.2, or compiled with **EXPERIMENTAL_DATE_SUPPORT=1** for 103 * php < 5.2). 104 * 105 * @return bool 106 * @api 107 */ 108 public static function isTimezoneSupportEnabled() 109 { 110 return 111 function_exists('date_create') && 112 function_exists('date_default_timezone_set') && 113 function_exists('timezone_identifiers_list') && 114 function_exists('timezone_open') && 115 function_exists('timezone_offset_get'); 116 } 117 118 /** 119 * Returns `true` if the GD PHP extension is available, `false` if otherwise. 120 * 121 * _Note: ImageGraph and the sparkline report visualization depend on the GD extension._ 122 * 123 * @return bool 124 * @api 125 */ 126 public static function isGdExtensionEnabled() 127 { 128 static $gd = null; 129 if (is_null($gd)) { 130 $gd = false; 131 132 $extensions = @get_loaded_extensions(); 133 if (is_array($extensions)) { 134 $gd = in_array('gd', $extensions) && function_exists('imageftbbox'); 135 } 136 } 137 138 return $gd; 139 } 140 141 /** 142 * Raise PHP memory limit if below the minimum required 143 * 144 * @return bool true if set; false otherwise 145 */ 146 public static function raiseMemoryLimitIfNecessary() 147 { 148 if (self::isArchivePhpTriggered()) { 149 // core:archive command: no time limit 150 self::setMaxExecutionTime( 0 ); 151 } 152 153 $memoryLimit = self::getMemoryLimitValue(); 154 if ($memoryLimit === false) { 155 return false; 156 } 157 $minimumMemoryLimit = Config::getInstance()->General['minimum_memory_limit']; 158 159 if (self::isArchivePhpTriggered()) { 160 // core:archive command: high memory limit 161 $minimumMemoryLimitWhenArchiving = Config::getInstance()->General['minimum_memory_limit_when_archiving']; 162 if ($memoryLimit < $minimumMemoryLimitWhenArchiving) { 163 return self::setMemoryLimit($minimumMemoryLimitWhenArchiving); 164 } 165 return false; 166 } 167 if ($memoryLimit < $minimumMemoryLimit) { 168 return self::setMemoryLimit($minimumMemoryLimit); 169 } 170 return false; 171 } 172 173 /** 174 * Set PHP memory limit 175 * 176 * Note: system settings may prevent scripts from overriding the master value 177 * 178 * @param int $minimumMemoryLimit 179 * @return bool true if set; false otherwise 180 */ 181 protected static function setMemoryLimit($minimumMemoryLimit) 182 { 183 // in Megabytes 184 $currentValue = self::getMemoryLimitValue(); 185 if ($currentValue === false 186 || ($currentValue < $minimumMemoryLimit && @ini_set('memory_limit', $minimumMemoryLimit . 'M')) 187 ) { 188 return true; 189 } 190 return false; 191 } 192 193 /** 194 * Get php memory_limit (in Megabytes) 195 * 196 * Prior to PHP 5.2.1, or on Windows, --enable-memory-limit is not a 197 * compile-time default, so ini_get('memory_limit') may return false. 198 * 199 * @return int|bool memory limit in megabytes, or false if there is no limit 200 */ 201 public static function getMemoryLimitValue() 202 { 203 if (($memory = ini_get('memory_limit')) > 0) { 204 return self::getMegaBytesFromShorthandByte($memory); 205 } 206 207 // no memory limit 208 return false; 209 } 210 211 /** 212 * Get php post_max_size (in Megabytes) 213 * 214 * @return int|bool max upload size in megabytes, or false if there is no limit 215 */ 216 public static function getPostMaxUploadSize() 217 { 218 if (($maxPostSize = ini_get('post_max_size')) > 0) { 219 return self::getMegaBytesFromShorthandByte($maxPostSize); 220 } 221 222 // no max upload size 223 return false; 224 } 225 226 /** 227 * @see http://www.php.net/manual/en/faq.using.php#faq.using.shorthandbytes 228 * @param $value 229 * @return false|float|int 230 */ 231 private static function getMegaBytesFromShorthandByte($value) 232 { 233 $value = str_replace(' ', '', $value); 234 235 $shorthandByteOption = substr($value, -1); 236 switch ($shorthandByteOption) { 237 case 'G': 238 case 'g': 239 return substr($value, 0, -1) * 1024; 240 case 'M': 241 case 'm': 242 return substr($value, 0, -1); 243 case 'K': 244 case 'k': 245 return substr($value, 0, -1) / 1024; 246 } 247 248 if (is_numeric($value)) { 249 return (int) $value / 1048576; 250 } 251 252 return false; 253 } 254 255 /** 256 * Set maximum script execution time. 257 * 258 * @param int $executionTime max execution time in seconds (0 = no limit) 259 */ 260 public static function setMaxExecutionTime($executionTime) 261 { 262 // in the event one or the other is disabled... 263 @ini_set('max_execution_time', $executionTime); 264 if (function_exists('set_time_limit')) { 265 @set_time_limit($executionTime); 266 } 267 } 268 269 public static function isMac() 270 { 271 return defined('PHP_OS') && PHP_OS === 'Darwin'; 272 } 273} 274