PageRenderTime 56ms CodeModel.GetById 28ms RepoModel.GetById 1ms app.codeStats 0ms

/wtf_core/functions.php

https://bitbucket.org/jsturgill/wordpress-theme-foundation
PHP | 358 lines | 301 code | 12 blank | 45 comment | 49 complexity | f3eae1270247be084f9e8a6931176171 MD5 | raw file
  1. <?php
  2. namespace WTFCore\Functions;
  3. $wtf_core_scripts = array();
  4. // Register scripts to be included in the footer. Every
  5. // registered script will only be included one time
  6. if ( ! function_exists( 'require_script' ) ) {
  7. function require_script( $name )
  8. {
  9. global $wtf_core_scripts;
  10. $url = get_bloginfo('stylesheet_directory').'/js/'.$name.'.js';
  11. $wtf_core_scripts[$name] = $url;
  12. }
  13. }
  14. if ( ! function_exists( 'draw_scripts' ) ) {
  15. function draw_scripts()
  16. {
  17. global $wtf_core_scripts;
  18. foreach ( $wtf_core_scripts as $name=>$url )
  19. {
  20. echo "<script type='text/javascript' src='{$url}'></script>";
  21. }
  22. }
  23. }
  24. // Automagically registers menus in a "theme_menus" array, if it is set.
  25. // Generally the child theme would create the array.
  26. if ( ! function_exists( 'register_menus' ) ) {
  27. function register_menus( $array )
  28. {
  29. $var = $array;
  30. $callback = function() use ( $var )
  31. {
  32. register_nav_menus( $var );
  33. };
  34. add_action( 'init', $callback );
  35. }
  36. if ( is_array( $theme_menus ) )
  37. {
  38. register_menus( $theme_menus );
  39. }
  40. }
  41. /* Returns the content within the specified layout.
  42. */
  43. if ( ! function_exists( 'get_html' ) ) {
  44. function get_html($layout, $content)
  45. {
  46. // TODO: Config file/constant to set layouts directory name
  47. $path = get_stylesheet_directory().'/layouts/'.$layout.'.php';
  48. ob_start();
  49. include( $path );
  50. $html = ob_get_clean();
  51. return $html;
  52. }
  53. }
  54. if ( ! function_exists( 'get_layout' ) ) {
  55. function get_layout()
  56. {
  57. // TODO: Config file/constant to set layouts directory name
  58. $root = get_stylesheet_directory().'/layouts/';
  59. $paths = array();
  60. if(is_tax()) {
  61. $taxonomy = get_query_var('taxonomy');
  62. $term = get_query_var('term');
  63. $paths[] = "taxonomy/{$taxonomy}-{$term}";
  64. $paths[] = "taxonomy/{$taxonomy}";
  65. $paths[] = "taxonomy/taxonomy";
  66. }
  67. if ( is_home() )
  68. {
  69. $paths[] = 'homepage';
  70. }
  71. $post_type = get_query_var( 'post_type' );
  72. if ( is_singular() )
  73. {
  74. $paths[] = "$post_type-single";
  75. // TODO: add ID checks for layout of single posts
  76. $paths[] = 'default-single';
  77. } else {
  78. $paths[] = "$post_type-plural";
  79. $paths[] = 'default-plural';
  80. }
  81. // TODO: add category check for layout
  82. // if ( is_category() )
  83. foreach($paths as $path)
  84. {
  85. if (file_exists("{$root}{$path}.php"))
  86. {
  87. return $path;
  88. }
  89. }
  90. return 'default';
  91. }
  92. }
  93. if ( ! function_exists( 'generate_filters_path_array' ) )
  94. {
  95. function generate_filters_path_array( $query_object )
  96. {
  97. if ( $query_object === null ) return null;
  98. $paths = array();
  99. $id = $query_object->query_vars['page_id'];
  100. $post_type = $query_object->query_vars['post_type'];
  101. $is_single = ( $query_object->is_single == FALSE ) ? FALSE : TRUE;
  102. // build array
  103. $paths[] = "{$post_type}/{$post_type}-{$id}";
  104. if ($is_single)
  105. {
  106. $paths[] = "{$post_type}/{$post_type}-single";
  107. } else {
  108. $paths[] = "{$post_type}/{$post_type}-plural";
  109. }
  110. $paths[] = "{$post_type}/{$post_type}-default";
  111. if ($is_single)
  112. {
  113. $paths[] = "default-single";
  114. } else {
  115. $paths[] = "default-plural";
  116. }
  117. $paths[] = "default";
  118. return $paths;
  119. }
  120. }
  121. if ( ! function_exists( 'generate_view_path_array' ) )
  122. {
  123. function generate_view_path_array( $post_object, $is_single = true, $is_tax = false )
  124. {
  125. $paths = array();
  126. $id = $post_object->ID;
  127. $post_type = get_post_type( $post_object );
  128. $post_custom_values = get_post_custom( $id );
  129. // TODO: Config file/constant to set view variable for WPF selector integration
  130. $view = $post_custom_values['select_view'];
  131. $view = ( is_array($view) && array_key_exists( 0, $view ) ) ? $view[0] : false;
  132. if($is_tax) {
  133. $taxonomy = get_query_var('taxonomy');
  134. $term = get_query_var('term');
  135. if ($template) $paths[] = $template;
  136. $paths[] = "{$post_type}/{$taxonomy}-{$term}-{$id}";
  137. $paths[] = "{$post_type}/{$taxonomy}-{$term}";
  138. $paths[] = "{$post_type}/{$taxonomy}-{$id}";
  139. $paths[] = "{$post_type}/{$taxonomy}";
  140. $paths[] = "{$post_type}/taxonomy-{$id}";
  141. $paths[] = "{$post_type}/taxonomy";
  142. if ($view) $paths[] = "{$post_type}/$view";
  143. $paths[] = "{$post_type}/{$post_type}-{$id}";
  144. $paths[] = "{$post_type}/{$post_type}-default";
  145. $paths[] = "{$taxonomy}-{$term}-{$id}";
  146. $paths[] = "{$taxonomy}-{$term}";
  147. $paths[] = "{$taxonomy}-{$id}";
  148. $paths[] = "{$taxonomy}";
  149. $paths[] = "taxonomy-{$id}";
  150. $paths[] = "taxonomy";
  151. $paths[] = "default";
  152. } else {
  153. if ($template) $paths[] = $template; // passed-in view overrides everything
  154. $paths[] = "{$post_type}/{$post_type}-{$id}"; // ID-specified template overried view selection
  155. if ($view) $paths[] = "{$post_type}/$view"; // specified view shortcuts typical delegation
  156. if ($is_single)
  157. {
  158. $paths[] = "{$post_type}/{$post_type}-single";
  159. } else {
  160. $paths[] = "{$post_type}/{$post_type}-plural";
  161. }
  162. $paths[] = "{$post_type}/{$post_type}-default";
  163. if ($is_single)
  164. {
  165. $paths[] = "default-single";
  166. } else {
  167. $paths[] = "default-plural";
  168. }
  169. $paths[] = "default";
  170. }
  171. return $paths;
  172. }
  173. }
  174. if ( ! function_exists( 'process_view_path_array' ) ) {
  175. function process_view_path_array( $paths )
  176. {
  177. // TODO: Config file/constant to set views directory name
  178. $root = get_stylesheet_directory().'/views/';
  179. if ( ! is_array( $paths ) )
  180. {
  181. // TODO: add a configuration flag for dev vs. production.
  182. // The paths error below should never be displayed in production
  183. echo '<p>Malformed paths array. Unable to display the post.';
  184. }
  185. foreach($paths as $path)
  186. {
  187. if (file_exists("{$root}{$path}.php"))
  188. {
  189. // echo "$root$path found.<br />"; // uncomment to troubleshoot
  190. include("{$root}{$path}.php");
  191. return;
  192. } else {
  193. // echo "$root$path not found.<br />"; // uncomment to troubleshoot
  194. }
  195. }
  196. // TODO: add a configuration flag for dev vs. production.
  197. // The paths array should never be displayed in production
  198. echo '<p>No template found. A template can be placed in any of the following locations:<br />
  199. (Root path: '.$root.' )</p>';
  200. pre($paths);
  201. return;
  202. }
  203. }
  204. /* Runs the WordPress loop and returns page content based on post type.
  205. */
  206. if ( ! function_exists( 'get_content' ) ) {
  207. function get_content( $template = null, $post_object = null )
  208. {
  209. global $post;
  210. ob_start();
  211. if ( $post_object === null && have_posts() === true ) {
  212. while ( have_posts()) {
  213. the_post();
  214. $paths = generate_view_path_array( $post, is_single(), is_tax() );
  215. if ( $template ) array_unshift( $paths, get_post_type() . '/' . $template, $template );
  216. process_view_path_array( $paths );
  217. }
  218. } elseif ( is_object( $post_object ) ) {
  219. $holder = $post;
  220. $post = $post_object;
  221. setup_postdata( $post );
  222. $paths = generate_view_path_array( $post ); // is_single = true, is_tax = false
  223. if ( $template ) array_unshift( $paths, get_post_type( $post_object ) . '/' . $template, $template );
  224. process_view_path_array( $paths );
  225. $post = $holder;
  226. wp_reset_query();
  227. } else {
  228. // TODO: Config file or constant to set no results view
  229. $root = get_stylesheet_directory().'/views/';
  230. include("{$root}no_results.php");
  231. }
  232. return $content = ob_get_clean();
  233. }
  234. }
  235. /* Prints the specified HTML chunk
  236. */
  237. if ( ! function_exists( 'render_chunk' ) ) {
  238. function render_chunk( $name )
  239. {
  240. // TODO: Config file/constant to set chunks directory name
  241. $path = get_stylesheet_directory().'/views/chunks/'.$name.'.php';
  242. if (file_exists($path)) { include($path); }
  243. }
  244. }
  245. function pre($variable)
  246. {
  247. echo "<pre>";
  248. print_r($variable);
  249. echo "</pre>";
  250. }
  251. if ( ! function_exists( 'render_view' ) ) {
  252. function render_view($view, $variables)
  253. {
  254. // TODO: Config file/constant to set views directory name
  255. extract($variables);
  256. include(get_stylesheet_directory().'/views/'.$view.'.php');
  257. }
  258. }
  259. // Use this function as the source of a pulldown field
  260. // in a metabox to allow views to be selected for a post type
  261. // if using WordPress Plugin Foundation code
  262. // See http://jeremiahsturgill.com for more information about WPF
  263. // Example manifest:
  264. /* - ID: view_selector
  265. Name: select_view_meta_box
  266. Title: Select View
  267. Post Type: page
  268. Context: side
  269. Fields:
  270. - Name: select_view
  271. Title: Select View
  272. Type: pulldown
  273. Source: \WTFCore\Functions\view_selector_options
  274. /**/
  275. if ( ! function_exists( 'view_selector_options' ) ) {
  276. function view_selector_options($field)
  277. {
  278. $post_type = get_post_type();
  279. $path = get_stylesheet_directory().'/views/'.$post_type.'/';
  280. $failure = array(array(
  281. 'value' =>'',
  282. 'text' =>'No views to choose from',)); // default value for failure
  283. $handle = opendir($path);
  284. $views = array();
  285. if ($handle !== false)
  286. {
  287. while ( false !== ($entry = readdir( $handle ) ) ) {
  288. if( $entry !=='.' && $entry !== '..' )
  289. {
  290. // Simple cleanup of filename to limit shenanigans possible
  291. // from a malitious filename.
  292. $option_value = str_replace(array('/', '\\', '.php', '.'), '', $entry);
  293. $option_display = esc_attr(str_replace('_', ' ', $option_value));
  294. $views[] = array('value' => $option_value,
  295. 'text' => $option_display);
  296. }
  297. }
  298. }
  299. return ( empty($views) ) ? $failure : $views; /**/
  300. }
  301. }
  302. // WPF integration helper.
  303. // Takes an array, a key, and an index.
  304. // Returns either false or a value
  305. if ( ! function_exists( 'get_array_entry' ) ) {
  306. function get_array_entry($custom, $key, $index = 0)
  307. {
  308. $default = array( $key => array( $index => false ) );
  309. $custom = array_merge( $default, (array)$custom );
  310. if ($index >= 0 )
  311. {
  312. return maybe_unserialize( $custom[$key][$index] );
  313. } else {
  314. foreach( $custom[$key] as $the_value)
  315. {
  316. $result[] = maybe_unserialize( $the_value );
  317. }
  318. return $result;
  319. }
  320. }
  321. }
  322. // Repurpose the view array to check for filters
  323. if ( ! function_exists( 'process_filters' ) )
  324. {
  325. function process_filters( $query_object = null )
  326. {
  327. $paths = \WTFCore\Functions\generate_filters_path_array( $query_object );
  328. if ( is_array( $paths ) )
  329. {
  330. $root = get_stylesheet_directory().'/filters/';
  331. // all filters will be included, not just the first found
  332. foreach ( $paths as $path )
  333. {
  334. if (file_exists( "{$root}{$path}.php" ))
  335. {
  336. include_once( "{$root}{$path}.php" );
  337. }
  338. }
  339. }
  340. }
  341. }
  342. // before the query is run
  343. add_action( 'pre_get_posts', '\WTFCore\Functions\process_filters' );