alpha.inc 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086
  1. <?php
  2. /**
  3. * @file
  4. * Helper functions for the Alpha base theme.
  5. */
  6. /**
  7. * A wrapper function for theme_get_settings().
  8. *
  9. * @param $name
  10. * The name of the setting that you want to retrieve.
  11. * @param $default (optional)
  12. * The name (key) of the theme that you want to fetch the
  13. * setting for. Defaults to NULL.
  14. * @param $theme (optional)
  15. * The key (machin-readable name) of a theme. Defaults to the key of the
  16. * current theme if not defined.
  17. *
  18. * @see
  19. * theme_get_setting().
  20. */
  21. function alpha_theme_get_setting($name, $default = NULL, $theme = NULL) {
  22. $setting = theme_get_setting($name, $theme);
  23. return isset($setting) ? $setting : $default;
  24. }
  25. /**
  26. * A helper function for retrieving zone settings.
  27. *
  28. * @param $name
  29. * The name of the setting that you want to retrieve.
  30. * @param $zone
  31. * The zone that you want to fetch the setting for.
  32. * @param $default (optional)
  33. * The name (key) of the theme that you want to fetch the
  34. * setting for. Defaults to NULL.
  35. * @param $theme (optional)
  36. * The key (machin-readable name) of a theme. Defaults to the key of the
  37. * current theme if not defined.
  38. *
  39. * @see
  40. * alpha_theme_get_setting().
  41. *
  42. * @see
  43. * theme_get_setting().
  44. */
  45. function alpha_zone_get_setting($name, $zone, $default = NULL, $theme = NULL) {
  46. $setting = theme_get_setting('alpha_zone_' . $zone . '_' . $name, $theme);
  47. return isset($setting) ? $setting : $default;
  48. }
  49. /**
  50. * A helper function for retrieving region settings.
  51. *
  52. * @param $name
  53. * The name of the setting that you want to retrieve.
  54. * @param $region
  55. * The region that you want to fetch the setting for.
  56. * @param $default (optional)
  57. * The name (key) of the theme that you want to fetch the
  58. * setting for. Defaults to NULL.
  59. * @param $theme (optional)
  60. * The key (machin-readable name) of a theme. Defaults to the key of the
  61. * current theme if not defined.
  62. *
  63. * @see
  64. * alpha_theme_get_setting().
  65. *
  66. * @see
  67. * theme_get_setting().
  68. */
  69. function alpha_region_get_setting($name, $region, $default = NULL, $theme = NULL) {
  70. $setting = theme_get_setting('alpha_region_' . $region . '_' . $name, $theme);
  71. return isset($setting) ? $setting : $default;
  72. }
  73. /**
  74. * Invokes a preprocess or process hook in all base themes aswell
  75. * as the subtheme (in that order) by including the corresponding
  76. * .inc file and calling the associated function.
  77. *
  78. * @param $type
  79. * The type of the hook. Can be preprocess or process.
  80. * @param $hook
  81. * The name of the hook.
  82. * @param &$vars
  83. * An array of variables belonging to the (pre)process hook.
  84. * Handed by reference.
  85. */
  86. function alpha_invoke($type, $hook, &$vars) {
  87. $theme = alpha_get_theme();
  88. // If one of the themes in the theme trail implements this hook
  89. // include the corresponding .inc file and call the associated function.
  90. foreach (alpha_theme_trail($theme->theme) as $key => $name) {
  91. $function = $key . '_alpha_' . $type . '_' . $hook;
  92. if (!function_exists($function)) {
  93. $file = drupal_get_path('theme', $key) . '/' . $type . '/' . $type . '-' . str_replace('_', '-', $hook) . '.inc';
  94. if (is_file($file)) {
  95. include $file;
  96. }
  97. }
  98. if (function_exists($function)) {
  99. $function($vars);
  100. }
  101. }
  102. }
  103. /**
  104. * This function "fixes" drupal_alter so it also works in the theme-settings and anywhere else
  105. * where you want to be 100% certain that drupal_alter uses the proper global $theme.
  106. *
  107. * The problem with drupal_alter is, that it always relies on the global $theme while
  108. * the theme-settings page relies (and "overrides") the global $theme_key variable while
  109. * building its form.
  110. *
  111. * @param $type
  112. * @param $data
  113. * @param $context1
  114. * @param $context2
  115. *
  116. * @see
  117. * See drupal_alter() for more information about how this works.
  118. */
  119. function alpha_alter($type, &$data, &$context1 = NULL, &$context2 = NULL) {
  120. global $theme, $base_theme_info;
  121. if ($theme != $context1) {
  122. $themes = list_themes();
  123. if (!empty($themes[$context1])) {
  124. $theme_original = $theme;
  125. $base_theme_info_original = $base_theme_info;
  126. foreach (alpha_theme_trail($context1) as $key => $title) {
  127. if (isset($themes[$key])) {
  128. $base_theme_info[$key] = $themes[$key];
  129. }
  130. }
  131. $functions = &drupal_static('drupal_alter');
  132. if (!empty($base_theme_info)) {
  133. foreach ($base_theme_info as $item) {
  134. if (is_file(drupal_get_path('theme', $item->name) . '/template.php')) {
  135. include_once drupal_get_path('theme', $item->name) . '/template.php';
  136. }
  137. }
  138. }
  139. array_pop($base_theme_info);
  140. $theme = $context1;
  141. drupal_alter($type, $data, $context1, $context2);
  142. $theme = $theme_original;
  143. $base_theme_info = $base_theme_info_original;
  144. unset($functions[$type]);
  145. }
  146. }
  147. else {
  148. drupal_alter($type, $data, $context1, $context2);
  149. }
  150. }
  151. /**
  152. * Builds the full theme trail (deepest base theme first, subtheme last)
  153. * for a theme.
  154. *
  155. * @param $theme
  156. * The key (machin-readable name) of a theme.
  157. *
  158. * @return
  159. * An array of all themes in the trail, keyed by theme key.
  160. */
  161. function alpha_theme_trail($theme) {
  162. $static = &drupal_static(__FUNCTION__);
  163. if (!isset($static)) {
  164. $themes = list_themes();
  165. if (isset($themes[$theme]->info['base theme'])) {
  166. foreach (system_find_base_themes($themes, $theme) as $base => $name) {
  167. if ($name && isset($themes[$base])) {
  168. $static[$theme][$base] = $themes[$base]->info['name'];
  169. }
  170. }
  171. }
  172. // Add our current subtheme ($key) to that array.
  173. if (isset($themes[$theme])) {
  174. $static[$theme][$theme] = $themes[$theme]->info['name'];
  175. }
  176. }
  177. if (isset($static[$theme])) {
  178. return $static[$theme];
  179. }
  180. }
  181. /**
  182. * Returns the theme container object for the current theme.
  183. *
  184. * @return
  185. * An object representing the current theme.
  186. */
  187. function alpha_get_theme() {
  188. $container = &drupal_static(__FUNCTION__);
  189. $key = $theme = $GLOBALS['theme_key'];
  190. $delta = NULL;
  191. if (module_exists('delta') && $delta = delta_get_current($theme)) {
  192. $key .= ':' . $delta;
  193. }
  194. if (!isset($container[$key])) {
  195. foreach (array_keys(alpha_theme_trail($theme)) as $item) {
  196. if (class_exists($item . '_theme_container')) {
  197. $class = $item . '_theme_container';
  198. }
  199. }
  200. if (isset($class)) {
  201. $container[$key] = new $class($theme, $delta);
  202. }
  203. }
  204. return $container[$key];
  205. }
  206. /**
  207. * Includes all activated libraries for the current theme.
  208. */
  209. function alpha_libraries_include() {
  210. $theme = alpha_get_theme();
  211. foreach (array_filter($theme->settings['libraries']) as $item => $status) {
  212. if (alpha_library_active($item)) {
  213. if (!empty($theme->libraries[$item]['js'])) {
  214. foreach ($theme->libraries[$item]['js'] as $include) {
  215. drupal_add_js($include['path'], $include['options']);
  216. }
  217. }
  218. if (!empty($theme->libraries[$item]['css'])) {
  219. foreach ($theme->libraries[$item]['css'] as $include) {
  220. drupal_add_css($include['path'], $include['options']);
  221. }
  222. }
  223. }
  224. }
  225. }
  226. /**
  227. * Includes all custom CSS files for the current theme.
  228. */
  229. function alpha_css_include() {
  230. $theme = alpha_get_theme();
  231. foreach (array_filter($theme->settings['css']) as $item => $status) {
  232. if (alpha_css_active($item)) {
  233. drupal_add_css($theme->css[$item]['path'], $theme->css[$item]['options']);
  234. }
  235. }
  236. }
  237. /**
  238. * Checks wether a library is active in the current theme.
  239. *
  240. * @param $library
  241. * The name of a library.
  242. *
  243. * @return
  244. * Boolean TRUE or FALSE.
  245. */
  246. function alpha_library_active($library) {
  247. $theme = alpha_get_theme();
  248. if (isset($theme->libraries[$library], $theme->settings['libraries'][$library]) && $theme->settings['libraries'][$library] === $library) {
  249. return TRUE;
  250. }
  251. return FALSE;
  252. }
  253. /**
  254. * Checks wether a custom CSS file is active in the current theme.
  255. *
  256. * @param $css
  257. * The filename of a CSS file.
  258. *
  259. * @return
  260. * Boolean TRUE or FALSE.
  261. */
  262. function alpha_css_active($css) {
  263. $theme = alpha_get_theme();
  264. if (isset($theme->css[$css], $theme->settings['css'][$css]) && $theme->settings['css'][$css] === $css) {
  265. return TRUE;
  266. }
  267. return FALSE;
  268. }
  269. /**
  270. * @deprecated
  271. */
  272. function alpha_regions() {
  273. return alpha_get_theme()->regions();
  274. }
  275. /**
  276. * @deprecated
  277. */
  278. function alpha_zones() {
  279. return alpha_get_theme()->zones();
  280. }
  281. /**
  282. * @deprecated
  283. */
  284. function alpha_sections() {
  285. return alpha_get_theme()->sections();
  286. }
  287. /**
  288. * @deprecated
  289. */
  290. function alpha_settings() {
  291. return alpha_get_theme()->settings();
  292. }
  293. /**
  294. * Includes all active layouts for a specific column count of the grid in
  295. * charge for the current theme and also adds the corresponding grid debugging
  296. * CSS if debugging is enabled.
  297. *
  298. * @param $columns
  299. * An integer value that declares the column layout that the grid CSS should
  300. * be generated for.
  301. */
  302. function alpha_grid_include($columns) {
  303. $processed = &drupal_static(__FUNCTION__);
  304. if (empty($processed[$columns])) {
  305. $processed[$columns] = TRUE;
  306. $theme = alpha_get_theme();
  307. if (!empty($theme->grid)) {
  308. foreach ($theme->grid as &$item) {
  309. if (empty($item['processed']) && (empty($item['columns']) || $item['columns'] == $columns)) {
  310. $item['processed'] = TRUE;
  311. drupal_add_css($item['item'], $item['options']);
  312. }
  313. }
  314. }
  315. if ($theme->settings['debug']['access'] && $theme->settings['debug']['grid']) {
  316. if (isset($theme->grids[$theme->settings['grid']])) {
  317. alpha_grid_debug($theme->grids[$theme->settings['grid']], $theme->settings['responsive'], $columns);
  318. }
  319. }
  320. }
  321. }
  322. /**
  323. * Generates and includes debugging information for a grid.
  324. *
  325. * @param $grid
  326. * A grid info array.
  327. * @param $responsive
  328. * A boolean indicating wether the grid debug CSS should be included in
  329. * responsive or non-responsive mode.
  330. * @param $columns
  331. * An integer value that declares the column layout that the grid debug
  332. * CSS should be included for.
  333. */
  334. function alpha_grid_debug($grid, $responsive, $columns) {
  335. if (isset($grid['columns'][$columns])) {
  336. if ($responsive) {
  337. $browsers = array('IE' => 'gte IE 9', '!IE' => TRUE);
  338. $layouts = array_keys($grid['layouts']);
  339. }
  340. else {
  341. $browsers = array('IE' => TRUE, '!IE' => TRUE);
  342. $layouts = isset($grid['layouts'][$grid['primary']]) ? array($grid['primary']) : array();
  343. }
  344. foreach ($layouts as $layout) {
  345. if ($grid['layouts'][$layout]['enabled'] || !$responsive) {
  346. $media = $responsive ? $grid['layouts'][$layout]['media'] : 'all';
  347. $weight = $grid['layouts'][$layout]['weight'];
  348. $sanitized = $grid['layouts'][$layout]['sanitized'];
  349. $file = $grid['path'] . '/' . $sanitized . '/' . $grid['sanitized'] . '-' . $sanitized . '-' . $columns . '.png';
  350. $overlay = '.alpha-grid-debug .container-' . $columns . ' { background-image: ' . (is_file($file) ? 'url(' . file_create_url($file) . ')' : 'none') . '; }';
  351. if ($responsive && $layout == $grid['primary']) {
  352. drupal_add_css($overlay, array(
  353. 'type' => 'inline',
  354. 'media' => 'all',
  355. 'browsers' => array('IE' => '(lt IE 9)&(!IEMobile)', '!IE' => FALSE),
  356. 'group' => -2000,
  357. 'weight' => $weight,
  358. ));
  359. }
  360. drupal_add_css($overlay, array(
  361. 'type' => 'inline',
  362. 'browsers' => $browsers,
  363. 'group' => -1000,
  364. 'weight' => $weight,
  365. 'media' => $media,
  366. ));
  367. }
  368. }
  369. }
  370. }
  371. /**
  372. * Builds an array of grid CSS information.
  373. *
  374. * @param $theme
  375. * The key (machin-readable name) of a theme.
  376. * @param $grid
  377. * A grid info array.
  378. * @param $responsive
  379. * A boolean indicating wether the grid CSS should be generated in
  380. * responsive or non-responsive mode.
  381. *
  382. * @return
  383. * An array of CSS files related to a grid.
  384. */
  385. function alpha_grid_css($theme, $grid, $responsive) {
  386. $columns = array_keys($grid['columns']);
  387. if ($responsive) {
  388. $browsers = array('IE' => 'gte IE 9', '!IE' => TRUE);
  389. $layouts = array_keys($grid['layouts']);
  390. }
  391. else {
  392. $browsers = array('IE' => TRUE, '!IE' => TRUE);
  393. $layouts = isset($grid['layouts'][$grid['primary']]) ? array($grid['primary']) : array();
  394. }
  395. $output = array();
  396. if (!empty($layouts)) {
  397. $trail = array_keys(alpha_theme_trail($theme));
  398. foreach ($layouts as $layout) {
  399. $enabled = $grid['layouts'][$layout]['enabled'];
  400. if (!$responsive || $enabled) {
  401. $media = $responsive ? $grid['layouts'][$layout]['media'] : 'all';
  402. $weight = $grid['layouts'][$layout]['weight'];
  403. $sanitized = $grid['layouts'][$layout]['sanitized'];
  404. $attached = array();
  405. foreach ($trail as $item) {
  406. $path = drupal_get_path('theme', $item) . '/css';
  407. $file = str_replace('_', '-', $item) . '-' . $grid['sanitized'];
  408. if ($item = alpha_find_stylesheet($path, $file)) {
  409. $attached[] = $item;
  410. }
  411. if ($item = alpha_find_stylesheet($path, $file . '-' . $sanitized)) {
  412. $attached[] = $item;
  413. }
  414. }
  415. foreach ($attached as $item) {
  416. $basename = $layout . '::' . $item;
  417. $output[$basename]['processed'] = FALSE;
  418. $output[$basename]['item'] = $basename;
  419. $output[$basename]['options'] = array(
  420. 'group' => 2000,
  421. 'weight' => $weight,
  422. 'data' => $item,
  423. 'basename' => $basename,
  424. 'media' => $media,
  425. 'browsers' => $browsers,
  426. 'preprocess_media' => TRUE,
  427. );
  428. if ($responsive && $grid['primary'] == $layout) {
  429. $basename = 'ie::' . $basename;
  430. $output[$basename]['processed'] = FALSE;
  431. $output[$basename]['item'] = $basename;
  432. $output[$basename]['options'] = array(
  433. 'group' => 1000,
  434. 'weight' => $weight,
  435. 'data' => $item,
  436. 'basename' => $basename,
  437. 'browsers' => array('IE' => '(lt IE 9)&(!IEMobile)', '!IE' => FALSE),
  438. );
  439. }
  440. }
  441. $path = $grid['path'] . '/' . $layout . '/' . $grid['sanitized'] . '-' . $sanitized;
  442. foreach ($columns as $count) {
  443. $file = $path . '-' . $count . '.css';
  444. $output[$file]['processed'] = FALSE;
  445. $output[$file]['columns'] = $count;
  446. $output[$file]['item'] = $file;
  447. $output[$file]['options'] = array(
  448. 'group' => 2000,
  449. 'weight' => $weight,
  450. 'media' => $media,
  451. 'browsers' => $browsers,
  452. 'preprocess_media' => TRUE,
  453. );
  454. if ($responsive && $grid['primary'] == $layout) {
  455. $basename = 'ie::' . $layout . '::' . $path . '-' . $count . '.css';
  456. $output[$basename]['processed'] = FALSE;
  457. $output[$basename]['columns'] = $count;
  458. $output[$basename]['item'] = $basename;
  459. $output[$basename]['options'] = array(
  460. 'group' => 1000,
  461. 'weight' => $weight,
  462. 'data' => $file,
  463. 'basename' => $basename,
  464. 'browsers' => array('IE' => '(lt IE 9)&(!IEMobile)', '!IE' => FALSE),
  465. );
  466. }
  467. }
  468. }
  469. }
  470. }
  471. return $output;
  472. }
  473. /**
  474. * Preprocesses CSS files so that CSS files that have 'preprocess_media'
  475. * set to TRUE are set to media="all" while having their former media query
  476. * added to the file content.
  477. *
  478. * @param $elements
  479. * An array of CSS files as in drupal_pre_render_styles().
  480. *
  481. * @return
  482. * An array of preprocessed CSS files.
  483. *
  484. * @see
  485. * drupal_pre_render_styles().
  486. */
  487. function alpha_css_preprocessor($elements) {
  488. $theme = alpha_get_theme();
  489. if ($theme->settings['responsive']) {
  490. $standard = array('all', 'screen', 'print', 'handheld', 'projection',
  491. 'tty', 'tv', 'aural', 'braille', 'embossed');
  492. foreach ($elements['#items'] as &$item) {
  493. if (!empty($item['preprocess_media']) && $item['type'] == 'file' && $item['preprocess'] && !in_array($item['media'], $standard)) {
  494. $item['data'] = alpha_css_cache_media_query($item);
  495. $item['media'] = 'all';
  496. }
  497. }
  498. }
  499. return $elements;
  500. }
  501. /**
  502. * @todo
  503. */
  504. function alpha_css_cache_media_query($item) {
  505. $map = variable_get('drupal_css_cache_files', array());
  506. $key = hash('sha256', serialize($item));
  507. $uri = isset($map[$key]) ? $map[$key] : NULL;
  508. if (empty($uri) || !file_exists($uri)) {
  509. // Build the base URL of this CSS file: start with the full URL.
  510. $base = file_create_url($item['data']);
  511. $base = substr($base, 0, strrpos($base, '/'));
  512. if (substr($base, 0, strlen($GLOBALS['base_root'])) == $GLOBALS['base_root']) {
  513. $base = substr($base, strlen($GLOBALS['base_root']));
  514. }
  515. _drupal_build_css_path(NULL, $base . '/');
  516. $data = drupal_load_stylesheet($item['data'], TRUE);
  517. // Anchor all paths in the CSS with its base URL, ignoring external and absolute paths.
  518. $data = preg_replace_callback('/url\(\s*[\'"]?(?![a-z]+:|\/+)([^\'")]+)[\'"]?\s*\)/i', '_drupal_build_css_path', $data);
  519. $data = '@media ' . $item['media'] . '{' . $data . '}';
  520. // Create the css/ within the files folder.
  521. $directory = 'public://css';
  522. $uri = $directory . '/css_' . drupal_hash_base64($data) . '.css';
  523. // Create the CSS file.
  524. file_prepare_directory($directory, FILE_CREATE_DIRECTORY);
  525. if (!file_exists($uri) && !file_unmanaged_save_data($data, $uri, FILE_EXISTS_REPLACE)) {
  526. return FALSE;
  527. }
  528. // If CSS gzip compression is enabled, clean URLs are enabled (which means
  529. // that rewrite rules are working) and the zlib extension is available then
  530. // create a gzipped version of this file. This file is served conditionally
  531. // to browsers that accept gzip using .htaccess rules.
  532. if (variable_get('css_gzip_compression', TRUE) && variable_get('clean_url', 0) && extension_loaded('zlib')) {
  533. if (!file_exists($uri . '.gz') && !file_unmanaged_save_data(gzencode($data, 9, FORCE_GZIP), $uri . '.gz', FILE_EXISTS_REPLACE)) {
  534. return FALSE;
  535. }
  536. }
  537. // Save the updated map.
  538. $map[$key] = $uri;
  539. variable_set('drupal_css_cache_files', $map);
  540. }
  541. return $uri;
  542. }
  543. /**
  544. * Clears the cache for the real theme or a delta template.
  545. *
  546. * @param $theme
  547. * The key (machin-readable name) of a theme.
  548. * @param $delta (optional)
  549. * The machine-readable name of a delta template.
  550. */
  551. function alpha_cache_clear($theme, $delta = NULL) {
  552. if (!isset($delta)) {
  553. cache_clear_all('alpha:' . $theme, 'cache');
  554. }
  555. else {
  556. cache_clear_all('alpha:' . $theme . ':' . $delta, 'cache');
  557. }
  558. }
  559. /**
  560. * Caches theme real theme or a delta template.
  561. *
  562. * @param $theme
  563. * The key (machin-readable name) of a theme.
  564. *
  565. * @return
  566. * The return value of cache_set().
  567. *
  568. * @see
  569. * cache_set().
  570. */
  571. function alpha_cache_set($theme) {
  572. $cache = new stdClass();
  573. foreach (array_keys($theme->cacheable()) as $item) {
  574. if (isset($theme->$item)) {
  575. $cache->$item = $theme->$item;
  576. }
  577. }
  578. if (isset($theme->delta)) {
  579. return cache_set('alpha:' . $theme->theme . ':' . $theme->delta, $cache);
  580. }
  581. else {
  582. return cache_set('alpha:' . $theme->theme, $cache);
  583. }
  584. }
  585. /**
  586. * Retrieves the cached parts of a theme container.
  587. *
  588. * @param $theme
  589. * The key (machin-readable name) of a theme.
  590. * @param $delta (optional)
  591. * The machine-readable name of a delta template.
  592. *
  593. * @return
  594. * A cache object or nothing if no cache entry exists.
  595. */
  596. function alpha_cache_get($theme, $delta = NULL) {
  597. if (isset($delta)) {
  598. return cache_get('alpha:' . $theme . ':' . $delta);
  599. }
  600. else {
  601. return cache_get('alpha:' . $theme);
  602. }
  603. }
  604. /**
  605. * Retrieve a list of CSS files that a theme may exclude via alpha_css_alter.
  606. *
  607. * @param $theme
  608. * The key (machin-readable name) of a theme.
  609. *
  610. * @return
  611. * An array of module and theme defined CSS files.
  612. */
  613. function alpha_retrieve_excludes($theme) {
  614. $themes = list_themes();
  615. $styles = array();
  616. foreach (system_rebuild_module_data() as $module => $data) {
  617. if ($data->status && !empty($data->info['stylesheets'])) {
  618. foreach ($data->info['stylesheets'] as $media => $content) {
  619. foreach ($content as $file) {
  620. $styles[$file] = array(
  621. 'type' => 'module',
  622. 'source' => $module,
  623. 'name' => $data->info['name'],
  624. 'file' => $file,
  625. 'media' => $media,
  626. 'description' => NULL,
  627. );
  628. }
  629. }
  630. }
  631. }
  632. foreach (alpha_info_trail('stylesheets', $theme) as $item => $data) {
  633. foreach ($data as $media => $content) {
  634. foreach ($content as $file) {
  635. $styles[$file] = array(
  636. 'type' => 'theme',
  637. 'source' => $item,
  638. 'name' => $themes[$item]->info['name'],
  639. 'file' => $file,
  640. 'media' => $media,
  641. 'description' => NULL,
  642. );
  643. }
  644. }
  645. }
  646. foreach (alpha_info_trail('exclude', $theme) as $item => $data) {
  647. foreach ($data as $file => $description) {
  648. $styles[$file] = array(
  649. 'type' => 'exclude',
  650. 'source' => $item,
  651. 'name' => $themes[$item]->info['name'],
  652. 'file' => $file,
  653. 'media' => NULL,
  654. 'description' => $description,
  655. );
  656. }
  657. }
  658. return $styles;
  659. }
  660. /**
  661. * Retrieves an array of available grids for a theme.
  662. *
  663. * @param $theme
  664. * The key (machin-readable name) of a theme.
  665. *
  666. * @return
  667. * An array containing all grid related information.
  668. */
  669. function alpha_retrieve_grids($theme) {
  670. $output = array();
  671. foreach (alpha_info_trail('grids', $theme) as $key => $data) {
  672. foreach ($data as $grid => $info) {
  673. $output[$grid] = array(
  674. 'theme' => $key,
  675. 'grid' => $grid,
  676. 'name' => $info['name'],
  677. 'sanitized' => str_replace('_', '-', $grid),
  678. 'layouts' => $info['layouts'],
  679. 'columns' => $info['columns'],
  680. 'path' => drupal_get_path('theme', $key) . '/css/grid/' . $grid,
  681. );
  682. $output[$grid]['primary'] = alpha_theme_get_setting('alpha_primary_' . $grid, key($info['layouts']), $theme);
  683. foreach ($output[$grid]['layouts'] as $layout => $title) {
  684. $output[$grid]['layouts'][$layout] = array(
  685. 'layout' => $layout,
  686. 'name' => $title,
  687. 'sanitized' => str_replace('_', '-', $layout),
  688. 'enabled' => alpha_theme_get_setting('alpha_layouts_' . $grid . '_' . $layout . '_responsive', FALSE, $theme),
  689. 'media' => alpha_theme_get_setting('alpha_layouts_' . $grid . '_' . $layout . '_media', 'all', $theme),
  690. 'weight' => alpha_theme_get_setting('alpha_layouts_' . $grid . '_' . $layout . '_weight', 0, $theme),
  691. );
  692. }
  693. uasort($output[$grid]['layouts'], 'alpha_sort_layouts');
  694. }
  695. }
  696. alpha_alter('alpha_grids', $output, $theme);
  697. return $output;
  698. }
  699. /**
  700. * Retrieves an array of available custom CSS files for a theme.
  701. *
  702. * @param $theme
  703. * The key (machin-readable name) of a theme.
  704. *
  705. * @return
  706. * An array of available CSS files.
  707. */
  708. function alpha_retrieve_css($theme) {
  709. $output = array();
  710. foreach (alpha_info_trail('css', $theme) as $key => $data) {
  711. foreach ($data as $name => $info) {
  712. $output[$name] = array(
  713. 'theme' => $key,
  714. 'file' => $name,
  715. 'path' => drupal_get_path('theme', $key) . '/' . (isset($info['path']) ? $info['path'] : 'css') . '/' . $name,
  716. 'options' => (isset($info['options']) ? $info['options'] : array()) + array('group' => CSS_THEME),
  717. 'name' => $info['name'],
  718. 'description' => isset($info['description']) ? $info['description'] : '',
  719. );
  720. }
  721. }
  722. alpha_alter('alpha_css', $output, $theme);
  723. return $output;
  724. }
  725. /**
  726. * Retrieves an array of available libraries for a theme.
  727. *
  728. * @param $theme
  729. * The key (machin-readable name) of a theme.
  730. *
  731. * @return
  732. * An array of available libraries.
  733. */
  734. function alpha_retrieve_libraries($theme) {
  735. $output = array();
  736. foreach (alpha_info_trail('libraries', $theme) as $key => $data) {
  737. foreach ($data as $name => $info) {
  738. $output[$name] = array(
  739. 'name' => $info['name'],
  740. 'description' => isset($info['info']['description']) ? $info['info']['description'] : '',
  741. );
  742. foreach (array('css', 'js') as $type) {
  743. if (!empty($info[$type])) {
  744. foreach ($info[$type] as $index => $item) {
  745. $output[$name][$type][$index] = array(
  746. 'file' => $item['file'],
  747. 'path' => drupal_get_path('theme', $key) . '/' . (isset($item['path']) ? $item['path'] : $type) . '/' . $item['file'],
  748. 'options' => (isset($item['options']) ? $item['options'] : array()) + array('group' => ($type == 'css' ? CSS_THEME : JS_THEME)),
  749. );
  750. }
  751. }
  752. }
  753. }
  754. }
  755. alpha_alter('alpha_libraries', $output, $theme);
  756. return $output;
  757. }
  758. /**
  759. * Recalculates the width of a primary element so that it fills the entire
  760. * container. This is useful in cases where you want to have a primary element
  761. * that consumes the empty space of one or more other elements that have been
  762. * removed.
  763. *
  764. * @param &$item
  765. * A list of grid elements.
  766. * @param $primary
  767. * The name of the primary element.
  768. * @param $container
  769. * The column count (width) of the container.
  770. */
  771. function alpha_calculate_primary(&$items, $primary, $container) {
  772. if (!empty($items)) {
  773. $items[$primary]['#grid']['columns'] = $container - $items[$primary]['#grid']['prefix'] - $items[$primary]['#grid']['suffix'];
  774. foreach (element_children($items) as $item) {
  775. if ($item != $primary) {
  776. $items[$primary]['#grid']['columns'] -= $items[$item]['#grid']['columns'] + $items[$item]['#grid']['prefix'] + $items[$item]['#grid']['suffix'];
  777. }
  778. }
  779. }
  780. }
  781. /**
  782. * Calculates the position of a element in a grid container by using the #weight
  783. * as the DOM position and then calculation the required pull and push CSS
  784. * classes to move the affected elements to their proper #position value.
  785. *
  786. * @param &$items
  787. * An array of grid elements.
  788. */
  789. function alpha_calculate_position(&$items) {
  790. if (!empty($items)) {
  791. $children = element_children($items, TRUE);
  792. foreach ($children as $a => $item) {
  793. foreach ($children as $b => $inner) {
  794. if ($item != $inner) {
  795. if ($a >= $b && $items[$item]['#position'] < $items[$inner]['#position']) {
  796. $items[$item]['#grid']['pull'] += $items[$inner]['#grid']['columns'] + $items[$inner]['#grid']['prefix'] + $items[$inner]['#grid']['suffix'];
  797. }
  798. else if ($a <= $b && $items[$item]['#position'] > $items[$inner]['#position']) {
  799. $items[$item]['#grid']['push'] += $items[$inner]['#grid']['columns'] + $items[$inner]['#grid']['prefix'] + $items[$inner]['#grid']['suffix'];
  800. }
  801. }
  802. }
  803. if ($items[$item]['#grid']['pull'] > $items[$item]['#grid']['push']) {
  804. $items[$item]['#grid']['pull'] -= $items[$item]['#grid']['push'];
  805. $items[$item]['#grid']['push'] = 0;
  806. }
  807. else if ($items[$item]['#grid']['pull'] > $items[$item]['#grid']['push']) {
  808. $items[$item]['#grid']['push'] -= $items[$item]['#grid']['pull'];
  809. $items[$item]['#grid']['pull'] = 0;
  810. }
  811. else if ($items[$item]['#grid']['pull'] == $items[$item]['#grid']['push']) {
  812. $items[$item]['#grid']['pull'] = 0;
  813. $items[$item]['#grid']['push'] = 0;
  814. }
  815. }
  816. }
  817. }
  818. /**
  819. * A helper function for retrieving the content of theme .info files
  820. * in the theme trail of $key.
  821. *
  822. * @param $item
  823. * The name of the variable that you want to fetch.
  824. * @param $theme
  825. * The key (machin-readable name) of a theme.
  826. * @return
  827. * The $item content of all themes .info files in the theme trail.
  828. */
  829. function alpha_info($item, $theme) {
  830. $themes = list_themes();
  831. if (!empty($themes[$theme]->info[$item])) {
  832. return $themes[$theme]->info[$item];
  833. }
  834. }
  835. /**
  836. * Retrieves a .info element for the active theme trail.
  837. *
  838. * @param $item
  839. * The name of the variable that you want to fetch.
  840. * @param $theme
  841. * The key (machin-readable name) of a theme.
  842. * @return
  843. * An array whoose keys are the theme names of the themes that provide
  844. * information about $item. The array values represent the information about
  845. * $item for the corresponding theme.
  846. */
  847. function alpha_info_trail($item, $theme) {
  848. $output = array();
  849. if ($trail = alpha_theme_trail($theme)) {
  850. $themes = list_themes();
  851. foreach ($trail as $key => $name) {
  852. if (!empty($themes[$key]->info[$item])) {
  853. $output[$key] = $themes[$key]->info[$item];
  854. }
  855. }
  856. }
  857. return $output;
  858. }
  859. /**
  860. * Searches for a CSS file $name in $path by looking for common file types.
  861. *
  862. * @param $path
  863. * The path of the folder that the file resides in.
  864. * @param $name
  865. * The name of the file that you are looking for.
  866. * @return
  867. * The path to the file if a file was found. FALSE otherwise.
  868. */
  869. function alpha_find_stylesheet($path, $name) {
  870. foreach (array('css', 'css.less', 'sass', 'scss') as $extension) {
  871. $file = $path . '/' . $name . '.' . $extension;
  872. if (is_file($file)) {
  873. return $file;
  874. }
  875. }
  876. return FALSE;
  877. }
  878. /**
  879. * A helper function to check wether the user defined by $user
  880. * matches one of the roles defined by $roles.
  881. *
  882. * @param $user
  883. * A Drupal user as returned by user_load().
  884. * @param $roles
  885. * An array of roles that you want to check against $user.
  886. * @return
  887. * A boolean, indicating wether or not $user matches one of
  888. * the $roles.
  889. */
  890. function alpha_debug_access($user, $roles) {
  891. foreach ($roles as $role) {
  892. if (isset($user->roles[$role])) {
  893. return TRUE;
  894. }
  895. }
  896. return FALSE;
  897. }
  898. /**
  899. * Helpfer function that sorts grid layouts.
  900. */
  901. function alpha_sort_layouts($a, $b) {
  902. if ($a['enabled'] && !$b['enabled']) {
  903. return -1;
  904. }
  905. else if ($b['enabled'] && !$a['enabled']) {
  906. return 1;
  907. }
  908. else if ($b['weight'] > $a['weight']) {
  909. return -1;
  910. }
  911. else if ($a['weight'] > $b['weight']) {
  912. return 1;
  913. }
  914. }
  915. /**
  916. * Helper function that returns an array of Drupal core elements that Alpha
  917. * can toggle on and off.
  918. */
  919. function alpha_toggle() {
  920. return array(
  921. 'messages' => t('Messages'),
  922. 'action_links' => t('Action links'),
  923. 'tabs' => t('Tabs'),
  924. 'breadcrumb' => t('Breadcrumb'),
  925. 'page_title' => t('Page title'),
  926. 'feed_icons' => t('Feed icons'),
  927. );
  928. }
  929. /**
  930. * Helper function that returns an array of Drupal core elements that Alpha
  931. * can hide via CSS.
  932. */
  933. function alpha_visibility() {
  934. return array(
  935. 'title' => t('Page title'),
  936. 'site_name' => t('Site name'),
  937. 'site_slogan' => t('Site slogan'),
  938. );
  939. }
  940. /**
  941. * A helper function that returns an array of un-supported Drupal core regions.
  942. */
  943. function alpha_regions_exclude() {
  944. return array('page_top', 'page_bottom');
  945. }