Theme.class.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485
  1. <?php
  2. /* vim: set expandtab sw=4 ts=4 sts=4: */
  3. /**
  4. * hold PMA_Theme class
  5. *
  6. * @package PhpMyAdmin
  7. */
  8. if (! defined('PHPMYADMIN')) {
  9. exit;
  10. }
  11. /**
  12. * handles theme
  13. *
  14. * @todo add the possibility to make a theme depend on another theme
  15. * and by default on original
  16. * @todo make all components optional - get missing components from 'parent' theme
  17. *
  18. * @package PhpMyAdmin
  19. */
  20. class PMA_Theme
  21. {
  22. /**
  23. * @var string theme version
  24. * @access protected
  25. */
  26. var $version = '0.0.0.0';
  27. /**
  28. * @var string theme name
  29. * @access protected
  30. */
  31. var $name = '';
  32. /**
  33. * @var string theme id
  34. * @access protected
  35. */
  36. var $id = '';
  37. /**
  38. * @var string theme path
  39. * @access protected
  40. */
  41. var $path = '';
  42. /**
  43. * @var string image path
  44. * @access protected
  45. */
  46. var $img_path = '';
  47. /**
  48. * @var integer last modification time for info file
  49. * @access protected
  50. */
  51. var $mtime_info = 0;
  52. /**
  53. * needed because sometimes, the mtime for different themes
  54. * is identical
  55. * @var integer filesize for info file
  56. * @access protected
  57. */
  58. var $filesize_info = 0;
  59. /**
  60. * @var array List of css files to load
  61. * @access private
  62. */
  63. private $_cssFiles = array(
  64. 'common',
  65. 'enum_editor',
  66. 'gis',
  67. 'navigation',
  68. 'pmd',
  69. 'rte',
  70. 'codemirror',
  71. 'jqplot',
  72. 'resizable-menu'
  73. );
  74. /**
  75. * Loads theme information
  76. *
  77. * @return boolean whether loading them info was successful or not
  78. * @access public
  79. */
  80. function loadInfo()
  81. {
  82. if (! file_exists($this->getPath() . '/info.inc.php')) {
  83. return false;
  84. }
  85. if ($this->mtime_info === filemtime($this->getPath() . '/info.inc.php')) {
  86. return true;
  87. }
  88. @include $this->getPath() . '/info.inc.php';
  89. // was it set correctly?
  90. if (! isset($theme_name)) {
  91. return false;
  92. }
  93. $this->mtime_info = filemtime($this->getPath() . '/info.inc.php');
  94. $this->filesize_info = filesize($this->getPath() . '/info.inc.php');
  95. if (isset($theme_full_version)) {
  96. $this->setVersion($theme_full_version);
  97. } elseif (isset($theme_generation, $theme_version)) {
  98. $this->setVersion($theme_generation . '.' . $theme_version);
  99. }
  100. $this->setName($theme_name);
  101. return true;
  102. }
  103. /**
  104. * returns theme object loaded from given folder
  105. * or false if theme is invalid
  106. *
  107. * @param string $folder path to theme
  108. *
  109. * @return PMA_Theme|false
  110. * @static
  111. * @access public
  112. */
  113. static public function load($folder)
  114. {
  115. $theme = new PMA_Theme();
  116. $theme->setPath($folder);
  117. if (! $theme->loadInfo()) {
  118. return false;
  119. }
  120. $theme->checkImgPath();
  121. return $theme;
  122. }
  123. /**
  124. * checks image path for existance - if not found use img from fallback theme
  125. *
  126. * @access public
  127. * @return bool
  128. */
  129. public function checkImgPath()
  130. {
  131. // try current theme first
  132. if (is_dir($this->getPath() . '/img/')) {
  133. $this->setImgPath($this->getPath() . '/img/');
  134. return true;
  135. }
  136. // try fallback theme
  137. $fallback = $GLOBALS['cfg']['ThemePath'] . '/'
  138. . PMA_Theme_Manager::FALLBACK_THEME
  139. . '/img/';
  140. if (is_dir($fallback)) {
  141. $this->setImgPath($fallback);
  142. return true;
  143. }
  144. // we failed
  145. trigger_error(
  146. sprintf(
  147. __('No valid image path for theme %s found!'),
  148. $this->getName()
  149. ),
  150. E_USER_ERROR
  151. );
  152. return false;
  153. }
  154. /**
  155. * returns path to theme
  156. *
  157. * @access public
  158. * @return string path to theme
  159. */
  160. public function getPath()
  161. {
  162. return $this->path;
  163. }
  164. /**
  165. * returns layout file
  166. *
  167. * @access public
  168. * @return string layout file
  169. */
  170. public function getLayoutFile()
  171. {
  172. return $this->getPath() . '/layout.inc.php';
  173. }
  174. /**
  175. * set path to theme
  176. *
  177. * @param string $path path to theme
  178. *
  179. * @return void
  180. * @access public
  181. */
  182. public function setPath($path)
  183. {
  184. $this->path = trim($path);
  185. }
  186. /**
  187. * sets version
  188. *
  189. * @param string $version version to set
  190. *
  191. * @return void
  192. * @access public
  193. */
  194. public function setVersion($version)
  195. {
  196. $this->version = trim($version);
  197. }
  198. /**
  199. * returns version
  200. *
  201. * @return string version
  202. * @access public
  203. */
  204. public function getVersion()
  205. {
  206. return $this->version;
  207. }
  208. /**
  209. * checks theme version agaisnt $version
  210. * returns true if theme version is equal or higher to $version
  211. *
  212. * @param string $version version to compare to
  213. *
  214. * @return boolean true if theme version is equal or higher to $version
  215. * @access public
  216. */
  217. public function checkVersion($version)
  218. {
  219. return version_compare($this->getVersion(), $version, 'lt');
  220. }
  221. /**
  222. * sets name
  223. *
  224. * @param string $name name to set
  225. *
  226. * @return void
  227. * @access public
  228. */
  229. public function setName($name)
  230. {
  231. $this->name = trim($name);
  232. }
  233. /**
  234. * returns name
  235. *
  236. * @access public
  237. * @return string name
  238. */
  239. public function getName()
  240. {
  241. return $this->name;
  242. }
  243. /**
  244. * sets id
  245. *
  246. * @param string $id new id
  247. *
  248. * @return void
  249. * @access public
  250. */
  251. public function setId($id)
  252. {
  253. $this->id = trim($id);
  254. }
  255. /**
  256. * returns id
  257. *
  258. * @return string id
  259. * @access public
  260. */
  261. public function getId()
  262. {
  263. return $this->id;
  264. }
  265. /**
  266. * Sets path to images for the theme
  267. *
  268. * @param string $path path to images for this theme
  269. *
  270. * @return void
  271. * @access public
  272. */
  273. public function setImgPath($path)
  274. {
  275. $this->img_path = $path;
  276. }
  277. /**
  278. * Returns the path to image for the theme.
  279. * If filename is given, it possibly fallbacks to fallback
  280. * theme for it if image does not exist.
  281. *
  282. * @param string $file file name for image
  283. *
  284. * @access public
  285. * @return string image path for this theme
  286. */
  287. public function getImgPath($file = null)
  288. {
  289. if (is_null($file)) {
  290. return $this->img_path;
  291. } else {
  292. if (is_readable($this->img_path . $file)) {
  293. return $this->img_path . $file;
  294. } else {
  295. return $GLOBALS['cfg']['ThemePath'] . '/'
  296. . PMA_Theme_Manager::FALLBACK_THEME . '/img/' . $file;
  297. }
  298. }
  299. }
  300. /**
  301. * load css (send to stdout, normally the browser)
  302. *
  303. * @return bool
  304. * @access public
  305. */
  306. public function loadCss()
  307. {
  308. $success = true;
  309. if ($GLOBALS['text_dir'] === 'ltr') {
  310. $right = 'right';
  311. $left = 'left';
  312. } else {
  313. $right = 'left';
  314. $left = 'right';
  315. }
  316. foreach ($this->_cssFiles as $file) {
  317. $path = $this->getPath() . "/css/$file.css.php";
  318. $fallback = "./themes/"
  319. . PMA_Theme_Manager::FALLBACK_THEME . "/css/$file.css.php";
  320. if (is_readable($path)) {
  321. echo "\n/* FILE: $file.css.php */\n";
  322. include $path;
  323. } else if (is_readable($fallback)) {
  324. echo "\n/* FILE: $file.css.php */\n";
  325. include $fallback;
  326. } else {
  327. $success = false;
  328. }
  329. }
  330. include './themes/sprites.css.php';
  331. return $success;
  332. }
  333. /**
  334. * Renders the preview for this theme
  335. *
  336. * @return string
  337. * @access public
  338. */
  339. public function getPrintPreview()
  340. {
  341. $url_params = array('set_theme' => $this->getId());
  342. $url = 'index.php' . PMA_URL_getCommon($url_params);
  343. $retval = '<div class="theme_preview">';
  344. $retval .= '<h2>';
  345. $retval .= htmlspecialchars($this->getName());
  346. $retval .= ' (' . htmlspecialchars($this->getVersion()) . ') ';
  347. $retval .= '</h2>';
  348. $retval .= '<p>';
  349. $retval .= '<a class="take_theme" ';
  350. $retval .= 'name="' . htmlspecialchars($this->getId()) . '" ';
  351. $retval .= 'href="' . $url . '">';
  352. if (@file_exists($this->getPath() . '/screen.png')) {
  353. // if screen exists then output
  354. $retval .= '<img src="' . $this->getPath() . '/screen.png" border="1"';
  355. $retval .= ' alt="' . htmlspecialchars($this->getName()) . '"';
  356. $retval .= ' title="' . htmlspecialchars($this->getName()) . '" />';
  357. $retval .= '<br />';
  358. } else {
  359. $retval .= __('No preview available.');
  360. }
  361. $retval .= '[ <strong>' . __('take it') . '</strong> ]';
  362. $retval .= '</a>';
  363. $retval .= '</p>';
  364. $retval .= '</div>';
  365. return $retval;
  366. }
  367. /**
  368. * Remove filter for IE.
  369. *
  370. * @return string CSS code.
  371. */
  372. function getCssIEClearFilter()
  373. {
  374. return PMA_USR_BROWSER_AGENT == 'IE'
  375. && PMA_USR_BROWSER_VER >= 6
  376. && PMA_USR_BROWSER_VER <= 8
  377. ? 'filter: none'
  378. : '';
  379. }
  380. /**
  381. * Gets currently configured font size.
  382. *
  383. * @return String with font size.
  384. */
  385. function getFontSize()
  386. {
  387. $fs = $GLOBALS['PMA_Config']->get('fontsize');
  388. if (!is_null($fs)) {
  389. return $fs;
  390. }
  391. if (isset($_COOKIE['pma_fontsize'])) {
  392. return $_COOKIE['pma_fontsize'];
  393. }
  394. return '82%';
  395. }
  396. /**
  397. * Generates code for CSS gradient using various browser extensions.
  398. *
  399. * @param string $start_color Color of gradient start, hex value without #
  400. * @param string $end_color Color of gradient end, hex value without #
  401. *
  402. * @return string CSS code.
  403. */
  404. function getCssGradient($start_color, $end_color)
  405. {
  406. $result = array();
  407. // Opera 9.5+, IE 9
  408. $result[] = 'background-image: url(./themes/svg_gradient.php?from='
  409. . $start_color . '&to=' . $end_color . ');';
  410. $result[] = 'background-size: 100% 100%;';
  411. // Safari 4-5, Chrome 1-9
  412. $result[] = 'background: '
  413. . '-webkit-gradient(linear, left top, left bottom, from(#'
  414. . $start_color . '), to(#' . $end_color . '));';
  415. // Safari 5.1, Chrome 10+
  416. $result[] = 'background: -webkit-linear-gradient(top, #'
  417. . $start_color . ', #' . $end_color . ');';
  418. // Firefox 3.6+
  419. $result[] = 'background: -moz-linear-gradient(top, #'
  420. . $start_color . ', #' . $end_color . ');';
  421. // IE 10
  422. $result[] = 'background: -ms-linear-gradient(top, #'
  423. . $start_color . ', #' . $end_color . ');';
  424. // Opera 11.10
  425. $result[] = 'background: -o-linear-gradient(top, #'
  426. . $start_color . ', #' . $end_color . ');';
  427. // IE 6-8
  428. if (PMA_USR_BROWSER_AGENT == 'IE'
  429. && PMA_USR_BROWSER_VER >= 6
  430. && PMA_USR_BROWSER_VER <= 8
  431. ) {
  432. $result[] = 'filter: '
  433. . 'progid:DXImageTransform.Microsoft.gradient(startColorstr="#'
  434. . $start_color . '", endColorstr="#' . $end_color . '");';
  435. }
  436. return implode("\n", $result);
  437. }
  438. }
  439. ?>