3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.7 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2016 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
34 * @package CiviCRM_Hook
35 * @copyright CiviCRM LLC (c) 2004-2016
40 * The "default" theme adapts based on the latest recommendation from civicrm.org
41 * by switching to DEFAULT_THEME at runtime.
43 const DEFAULT_THEME
= 'greenwich';
46 * Fallback is a pseudotheme which can be included in "search_order".
47 * It locates files in the core/extension (non-theme) codebase.
49 const FALLBACK_THEME
= '_fallback_';
51 const PASSTHRU
= 'PASSTHRU';
57 private $activeThemeKey = NULL;
61 * Array(string $themeKey => array $themeSpec).
63 private $themes = NULL;
66 * @var \CRM_Utils_Cache_Interface
68 private $cache = NULL;
72 * @param \CRM_Utils_Cache_Interface $cache
74 public function __construct($cache = NULL) {
75 $this->cache
= $cache ?
$cache : Civi
::cache('long');
79 * Determine the name of active theme.
84 public function getActiveThemeKey() {
85 if ($this->activeThemeKey
=== NULL) {
86 // Ambivalent: is it better to use $config->userFrameworkFrontend or $template->get('urlIsPublic')?
87 $config = \CRM_Core_Config
::singleton();
88 $settingKey = $config->userFrameworkFrontend ?
'theme_frontend' : 'theme_backend';
90 $themeKey = Civi
::settings()->get($settingKey);
91 if ($themeKey === 'default') {
92 $themeKey = self
::DEFAULT_THEME
;
95 \CRM_Utils_Hook
::activeTheme($themeKey, [
97 'page' => \CRM_Utils_Array
::value(\CRM_Core_Config
::singleton()->userFrameworkURLVar
, $_GET),
100 $themes = $this->getAll();
101 $this->activeThemeKey
= isset($themes[$themeKey]) ?
$themeKey : self
::DEFAULT_THEME
;
103 return $this->activeThemeKey
;
107 * Get the definition of the theme.
109 * @param string $themeKey
110 * Ex: 'greenwich', 'shoreditch'.
112 * @see CRM_Utils_Hook::themes
114 public function get($themeKey) {
115 $all = $this->getAll();
116 return isset($all[$themeKey]) ?
$all[$themeKey] : NULL;
120 * Get a list of all known themes, including hidden base themes.
123 * List of themes, keyed by name. Same format as CRM_Utils_Hook::themes(),
124 * but any default values are filled in.
125 * @see CRM_Utils_Hook::themes
127 public function getAll() {
128 if ($this->themes
=== NULL) {
129 // Cache includes URLs/paths, which change with runtime.
130 $cacheKey = 'theme_list_' . \CRM_Core_Config_Runtime
::getId();
131 $this->themes
= $this->cache
->get($cacheKey);
132 if ($this->themes
=== NULL) {
133 $this->themes
= $this->buildAll();
134 $this->cache
->set($cacheKey, $this->themes
);
137 return $this->themes
;
141 * Get a list of available themes, excluding hidden base themes.
143 * This is the same as getAll(), but abstract themes like "_fallback_"
144 * or "_newyork_base_" are omitted.
148 * Ex: ['greenwich' => 'Greenwich', 'shoreditch' => 'Shoreditch'].
149 * @see CRM_Utils_Hook::themes
151 public function getAvailable() {
153 foreach ($this->getAll() as $key => $theme) {
154 if ($key{0} !== '_') {
155 $result[$key] = $theme['title'];
162 * Get the URL(s) for a themed CSS file.
164 * This implements a prioritized search, in order:
165 * - Check for the specified theme.
166 * - If that doesn't exist, check for the default theme.
167 * - If that doesn't exist, use the 'none' theme.
169 * @param string $active
172 * @param string $cssExt
174 * @param string $cssFile
175 * Ex: 'css/bootstrap.css' or 'css/civicrm.css'.
177 * List of URLs to display.
178 * Ex: array(string $url)
180 public function resolveUrls($active, $cssExt, $cssFile) {
181 $all = $this->getAll();
182 if (!isset($all[$active])) {
186 $cssId = $this->cssId($cssExt, $cssFile);
188 foreach ($all[$active]['search_order'] as $themeKey) {
189 if (isset($all[$themeKey]['excludes']) && in_array($cssId, $all[$themeKey]['excludes'])) {
193 $result = Civi\Core\Resolver
::singleton()
194 ->call($all[$themeKey]['url_callback'], array($this, $themeKey, $cssExt, $cssFile));
197 if ($result !== self
::PASSTHRU
) {
202 throw new \
RuntimeException("Failed to resolve URL. Theme metadata may be incomplete.");
206 * Construct the list of available themes.
209 * List of themes, keyed by name.
210 * @see CRM_Utils_Hook::themes
212 protected function buildAll() {
216 'title' => ts('Automatic'),
217 'help' => ts('Determine a system default automatically'),
218 // This is an alias. url_callback, search_order don't matter.
220 'greenwich' => array(
222 'title' => 'Greenwich',
223 'help' => ts('CiviCRM 4.x look-and-feel'),
227 'title' => ts('None (Unstyled)'),
228 'help' => ts('Disable CiviCRM\'s built-in CSS files.'),
229 'search_order' => array('none', self
::FALLBACK_THEME
),
235 self
::FALLBACK_THEME
=> array(
237 'title' => 'Fallback (Abstract Base Theme)',
238 'url_callback' => '\Civi\Core\Themes\Resolvers::fallback',
239 'search_order' => array(self
::FALLBACK_THEME
),
243 \CRM_Utils_Hook
::themes($themes);
245 foreach (array_keys($themes) as $themeKey) {
246 $themes[$themeKey] = $this->build($themeKey, $themes[$themeKey]);
253 * Apply defaults for a given them.
255 * @param string $themeKey
256 * The name of the theme. Ex: 'greenwich'.
257 * @param array $theme
258 * The original theme definition of the theme (per CRM_Utils_Hook::themes).
260 * The full theme definition of the theme (per CRM_Utils_Hook::themes).
261 * @see CRM_Utils_Hook::themes
263 protected function build($themeKey, $theme) {
266 'url_callback' => '\Civi\Core\Themes\Resolvers::simple',
267 'search_order' => array($themeKey, self
::FALLBACK_THEME
),
269 $theme = array_merge($defaults, $theme);
275 * @param string $cssExt
276 * @param string $cssFile
279 public function cssId($cssExt, $cssFile) {
280 return ($cssExt === 'civicrm') ?
$cssFile : "$cssExt-$cssFile";