Context.inc 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. <?php
  2. namespace Memcache_UI\Core {
  3. class Context {
  4. protected $logLevelClasses = NULL;
  5. /**
  6. * Base URL for the script, for HTTP paths
  7. *
  8. * @var string
  9. */
  10. protected $base;
  11. /**
  12. * Base directory for the script, for file operations
  13. */
  14. protected $directory;
  15. /**
  16. * Graphics context
  17. *
  18. * @var GraphicsContext
  19. */
  20. protected $gc = NULL;
  21. /**
  22. * Locale with encoding
  23. *
  24. * This is a static because a page runs for only one locale.
  25. */
  26. protected static $locale = 'en_US.UTF8';
  27. /**
  28. * Logging level, as per RFC5424
  29. *
  30. * @link http://php.net/network.constants.php
  31. *
  32. * @var integer
  33. */
  34. protected $logLevel = NULL;
  35. /**
  36. * Messages for display.
  37. *
  38. * @var array
  39. */
  40. protected $messages = array();
  41. /**
  42. * Requested path: <$PHP_SELF>?q=a/b/c
  43. *
  44. * @var string
  45. */
  46. protected $path = NULL;
  47. /**
  48. * Tidy the output ?
  49. *
  50. * @var boolean
  51. */
  52. protected $tidy = NULL;
  53. /**
  54. * User information: logged or not ?
  55. *
  56. * @var boolean
  57. */
  58. protected $user = FALSE;
  59. function __construct() {
  60. $this->initLocale(); // Check extension and initialize locale
  61. $this->getTidy(); // Needed to check optional extension
  62. }
  63. function __destruct() {
  64. if (!empty($this->messages)) {
  65. $ret = (string) new Element('pre', array('class' => array('messages')),
  66. implode("\n", $this->getMessage(TRUE)));
  67. echo $ret;
  68. }
  69. }
  70. function __toString() {
  71. $ret = '<pre>' . print_r($this, TRUE) . '</pre>';
  72. return $ret;
  73. }
  74. /**
  75. * Get the base path where the script is located.
  76. *
  77. * This is helpful to locate other files using paths relative to the install.
  78. */
  79. public function getBase() {
  80. if (!isset($this->base)) {
  81. $this->base = dirname($_SERVER['SCRIPT_NAME']);
  82. if ($this->base == '/') {
  83. $this->base = '';
  84. }
  85. }
  86. return $this->base;
  87. }
  88. public function getDirectory() {
  89. if (!isset($this->directory)) {
  90. $this->directory = dirname($_SERVER['SCRIPT_FILENAME']);
  91. }
  92. return $this->directory;
  93. }
  94. public function getLogLevel() {
  95. if (!isset($this->logLevel)) {
  96. $usLogLevel = NULL;
  97. foreach ($_GET as $key => $value) {
  98. if (strtolower($key) === 'loglevel') {
  99. $usLogLevel = (int) $value;
  100. break;
  101. }
  102. }
  103. if (!isset($usLogLevel)) {
  104. $usLogLevel = LOG_NOTICE;
  105. }
  106. if ($usLogLevel < LOG_EMERG) {
  107. $this->logLevel = LOG_EMERG;
  108. }
  109. elseif ($usLogLevel > LOG_DEBUG) {
  110. $this->logLevel = LOG_DEBUG;
  111. }
  112. else {
  113. $this->logLevel = $usLogLevel; // We now know it to be safe
  114. }
  115. }
  116. return $this->logLevel;
  117. }
  118. public function getLogLevelClass($logLevel) {
  119. if (!isset($this->logLevelClasses)) {
  120. $this->logLevelClasses = array(
  121. LOG_EMERG => 'error',
  122. LOG_ALERT => 'error',
  123. LOG_CRIT => 'error',
  124. LOG_ERR => 'error',
  125. LOG_WARNING => 'warning',
  126. LOG_NOTICE => 'warning',
  127. LOG_INFO => 'status',
  128. LOG_DEBUG => 'status',
  129. );
  130. }
  131. if ($logLevel < LOG_EMERG) {
  132. $logLevel = LOG_EMERG;
  133. }
  134. elseif ($logLevel > LOG_DEBUG) {
  135. $logLevel = LOG_DEBUG;
  136. }
  137. return $this->logLevelClasses[$logLevel];
  138. }
  139. public function getMessage($clear = FALSE) {
  140. $ret = $this->messages;
  141. if ($clear) {
  142. $this->messages = array();
  143. }
  144. return $ret;
  145. }
  146. /**
  147. * Return the requested path.
  148. *
  149. * @param string $path
  150. */
  151. public function getPath() {
  152. if (!isset($this->path)) {
  153. $this->path = empty($_GET['q']) ? '' : $_GET['q'];
  154. }
  155. return $this->path;
  156. }
  157. /**
  158. * Return the "tidy" status.
  159. *
  160. * Will only be TRUE if requested (possibly by default) and extension is
  161. * loaded. A warning will be generated if tidy is requested but extension is
  162. * not loaded.
  163. */
  164. public function getTidy() {
  165. static $notified = FALSE;
  166. if (!isset($this->tidy)) {
  167. $this->tidy = TRUE;
  168. foreach ($_GET as $key => $value) {
  169. if (strtolower($key) === 'tidy') {
  170. $this->tidy = !!$value;
  171. break;
  172. }
  173. }
  174. if (!$notified && $this->tidy && !extension_loaded('tidy')) {
  175. $this->setMessage(t('Extension @tidy requested but missing: output formatting unavailable.', array(
  176. '@tidy' => 'tidy',
  177. )), LOG_WARNING);
  178. $notified = TRUE;
  179. $this->tidy = FALSE;
  180. }
  181. }
  182. return $this->tidy;
  183. }
  184. /**
  185. * Initialize the locale based on the user Accept-Language header.
  186. *
  187. * @TODO support "xx" form, and not just "xx_YY".
  188. * @TODO support more platforms. UNIX and MacOS X do not handle locales like Linux
  189. *
  190. * @link @link http://www.php.net/manual/fr/function.bind-textdomain-codeset.php#42631
  191. *
  192. * @return void
  193. */
  194. protected function initLocale() {
  195. static $notified = FALSE;
  196. if (!$notified && !extension_loaded('intl')) {
  197. // Do not invoke t() before initializing locale
  198. $this->setMessage(strtr('Extension @intl requested but missing: translations unavailable.', array(
  199. '@intl' => 'intl',
  200. )), LOG_WARNING);
  201. }
  202. else {
  203. $locale = \Locale::acceptFromHttp($_SERVER['HTTP_ACCEPT_LANGUAGE']);
  204. $this->setMessage(strtr('Requested locale: @locale', array('@locale' => $locale)), LOG_DEBUG);
  205. if (!empty($locale)) {
  206. $matches = array();
  207. $count = preg_match('/^([a-z]{2}_[A-Z]{2})(\.(\w+))*/', $locale, $matches);
  208. if ($count) {
  209. $count = count($matches);
  210. }
  211. $locale = $count >= 2
  212. ? $matches[1]
  213. : 'en_US';
  214. $codeset = $count >= 4
  215. ? $matches[3]
  216. : 'UTF8';
  217. self::$locale = $locale . '.' . $codeset;
  218. setlocale(LC_ALL, self::$locale);
  219. $domain = 'messages';
  220. $translation_path = 'locale';
  221. bindtextdomain($domain, $translation_path);
  222. textdomain($domain);
  223. bind_textdomain_codeset($domain, 'UTF8');
  224. $this->setMessage(self::t('Locale: @locale', array('@locale' => self::$locale)), LOG_DEBUG);
  225. }
  226. }
  227. }
  228. /**
  229. * Add a message to the messages list if it is above the current logging level.
  230. *
  231. * @param string $text
  232. * @param integer $logLevel
  233. *
  234. * @return void
  235. */
  236. public function setMessage($text, $logLevel = LOG_NOTICE) {
  237. if ($logLevel <= $this->getlogLevel()) {
  238. if (is_array($text) || (is_object($text) && !method_exists($text, '__toString'))) {
  239. $this->messages[] = array('<pre>' . print_r($text, TRUE) . '</pre>', $logLevel);
  240. }
  241. else {
  242. $this->messages[] = array((string) $text, $logLevel);
  243. }
  244. }
  245. }
  246. /**
  247. * Wrapper to combine gettext translation and parameter substitution.
  248. *
  249. * @param string $message
  250. * @param array $args
  251. *
  252. * @return string
  253. */
  254. static function t($message, $args = array()) {
  255. return strtr(gettext($message), $args);
  256. }
  257. /**
  258. * Embryonic version of Drupal url().
  259. *
  260. * @param string $path
  261. * @param array $options
  262. * - No option currently recognized.
  263. * - 'absolute' likely at some point
  264. *
  265. * @return string
  266. */
  267. static function url($path = NULL, $options = array()) {
  268. $options += array(
  269. // 'absolute' => FALSE,
  270. );
  271. return $this->getBase() . '?q=' . urlencode($path);
  272. }
  273. }
  274. }