PageRenderTime 58ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 1ms

/sermon-browser/sermon.php

https://github.com/Jarrod-Williams/Sermons-Browser-Plugin
PHP | 876 lines | 580 code | 47 blank | 249 comment | 151 complexity | e058a5b3bff78b649b42b7c965ea1c44 MD5 | raw file
  1. <?php
  2. /*
  3. Plugin Name: Sermon Browser
  4. Plugin URI: http://www.4-14.org.uk/sermon-browser
  5. Description: Add sermons to your Wordpress blog. Thanks to <a href="http://codeandmore.com/">Tien Do Xuan</a> for initial coding.
  6. Author: Mark Barnes
  7. Version: 0.43.5
  8. Author URI: http://www.4-14.org.uk/
  9. Copyright (c) 2008-2009 Mark Barnes
  10. This program is free software: you can redistribute it and/or modify
  11. it under the terms of the GNU General Public License as published by
  12. the Free Software Foundation, either version 3 of the License, or
  13. (at your option) any later version.
  14. This program is distributed in the hope that it will be useful,
  15. but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. GNU General Public License for more details.
  18. You should have received a copy of the GNU General Public License
  19. along with this program. If not, see <http://www.gnu.org/licenses/>.
  20. The structure of this plugin is as follows:
  21. ===========================================
  22. MAIN FILES
  23. ----------
  24. sermon.php - This file. Contains common functions and initialisation routines.
  25. admin.php - Functions required in the admin pages.
  26. frontend.php - Functions required in the frontend (non-admin) pages.
  27. OTHER FILES
  28. -----------
  29. ajax.php - Handles AJAX returns.
  30. dictionary.php - Translates the template tags into php code. Used only when saving a template.
  31. filetypes.php - User-editable file, which returns the correct mime-type for common file-extensions.
  32. php4compat.php - Small number of functions required for PHP4 compatibility
  33. podcast.php - Handles the podcast feed
  34. sb-install.php - Used only when installing the plugin for the first time
  35. style.php - Outputs the custom stylesheet
  36. uninstall.php - Removes the plugin and its databases tables and rows
  37. upgrade.php - Runs only when upgrading from earlier versions of SermonBrowser
  38. If you want to follow the logic of the code, start with sb_sermon_init, and trace the Wordpress actions and filters.
  39. The frontend output is inserted by sb_shortcode
  40. */
  41. /**
  42. * Initialisation
  43. *
  44. * Sets version constants and basic Wordpress hooks.
  45. * @package common_functions
  46. */
  47. define('SB_CURRENT_VERSION', '0.43.5');
  48. define('SB_DATABASE_VERSION', '1.6');
  49. add_action ('plugins_loaded', 'sb_hijack');
  50. add_action ('init', 'sb_sermon_init');
  51. add_action ('widgets_init', 'sb_widget_sermon_init');
  52. if (version_compare(PHP_VERSION, '5.0.0', '<'))
  53. require('sb-includes/php4compat.php');
  54. /**
  55. * Display podcast, or download linked files
  56. *
  57. * Intercepts Wordpress at earliest opportunity. Checks whether the following are required before the full framework is loaded:
  58. * Ajax data, stylesheet, file download
  59. */
  60. function sb_hijack() {
  61. global $filetypes, $wpdb, $sermon_domain;
  62. sb_define_constants();
  63. if (function_exists('wp_timezone_supported') && wp_timezone_supported())
  64. wp_timezone_override_offset();
  65. if (isset($_POST['sermon']) && $_POST['sermon'] == 1)
  66. require('sb-includes/ajax.php');
  67. if (stripos($_SERVER['REQUEST_URI'], 'sb-style.css') !== FALSE || isset($_GET['sb-style']))
  68. require('sb-includes/style.php');
  69. //Forces sermon download of local file
  70. if (isset($_GET['download']) AND isset($_GET['file_name'])) {
  71. $file_name = $wpdb->escape(urldecode($_GET['file_name']));
  72. $file_name = $wpdb->get_var("SELECT name FROM {$wpdb->prefix}sb_stuff WHERE name='{$file_name}'");
  73. if (!is_null($file_name)) {
  74. header("Pragma: public");
  75. header("Expires: 0");
  76. header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
  77. header("Content-Type: application/force-download");
  78. header("Content-Type: application/octet-stream");
  79. header("Content-Type: application/download");
  80. header('Content-Disposition: attachment; filename="'.$file_name.'";');
  81. header("Content-Transfer-Encoding: binary");
  82. sb_increase_download_count ($file_name);
  83. $file_name = SB_ABSPATH.sb_get_option('upload_dir').$file_name;
  84. $filesize = filesize($file_name);
  85. if ($filesize != 0)
  86. header("Content-Length: ".filesize($file_name));
  87. output_file($file_name);
  88. die();
  89. } else
  90. wp_die(urldecode($_GET['file_name']).' '.__('not found', $sermon_domain), __('File not found', $sermon_domain), array('response' => 404));
  91. }
  92. //Forces sermon download of external URL
  93. if (isset($_REQUEST['download']) AND isset($_REQUEST['url'])) {
  94. $url = urldecode($_GET['url']);
  95. if(ini_get('allow_url_fopen')) {
  96. $headers = @get_headers($url, 1);
  97. if ($headers === FALSE || (isset($headers[0]) && strstr($headers[0], '404') !== FALSE))
  98. wp_die(urldecode($_GET['url']).' '.__('not found', $sermon_domain), __('URL not found', $sermon_domain), array('response' => 404));
  99. $headers = array_change_key_case($headers,CASE_LOWER);
  100. if (isset($headers['location'])) {
  101. $location = $headers['location'];
  102. if (is_array($location))
  103. $location = $location[0];
  104. if ($location && substr($location,0,7) != "http://") {
  105. preg_match('@^(?:http://)?([^/]+)@i', $url, $matches);
  106. $location = "http://".$matches[1].'/'.$location;
  107. }
  108. if ($location) {
  109. header('Location: '.get_bloginfo('wpurl').'?download&url='.$location);
  110. die();
  111. }
  112. }
  113. header("Pragma: public");
  114. header("Expires: 0");
  115. header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
  116. header("Content-Type: application/force-download");
  117. header("Content-Type: application/octet-stream");
  118. header("Content-Type: application/download");
  119. if (isset($headers['last-modified']))
  120. header('Last-Modified: '.$headers['last-modified']);
  121. if (isset($headers['content-length']))
  122. header("Content-Length: ".$headers['content-length']);
  123. if (isset($headers['content-disposition']))
  124. header ('Content-Disposition: '.$headers['content-disposition']);
  125. else
  126. header('Content-Disposition: attachment; filename="'.basename($url).'";');
  127. header("Content-Transfer-Encoding: binary");
  128. header($_SERVER['SERVER_PROTOCOL'].' 200 OK');
  129. sb_increase_download_count($url);
  130. session_write_close();
  131. while (@ob_end_clean());
  132. output_file($url);
  133. die();
  134. } else {
  135. sb_increase_download_count ($url);
  136. header('Location: '.$url);
  137. die();
  138. }
  139. }
  140. //Returns local file (doesn't force download)
  141. if (isset($_GET['show']) AND isset($_GET['file_name'])) {
  142. global $filetypes;
  143. $file_name = $wpdb->escape(urldecode($_GET['file_name']));
  144. $file_name = $wpdb->get_var("SELECT name FROM {$wpdb->prefix}sb_stuff WHERE name='{$file_name}'");
  145. if (!is_null($file_name)) {
  146. $url = sb_get_option('upload_url').$file_name;
  147. sb_increase_download_count ($file_name);
  148. header("Location: ".$url);
  149. die();
  150. } else
  151. wp_die(urldecode($_GET['file_name']).' '.__('not found', $sermon_domain), __('File not found', $sermon_domain), array('response' => 404));
  152. }
  153. //Returns contents of external URL(doesn't force download)
  154. if (isset($_REQUEST['show']) AND isset($_REQUEST['url'])) {
  155. $url = URLDecode($_GET['url']);
  156. sb_increase_download_count ($url);
  157. header('Location: '.$url);
  158. die();
  159. }
  160. }
  161. /**
  162. * Main initialisation function
  163. *
  164. * Sets up most Wordpress hooks and filters, depending on whether request is for front or back end.
  165. */
  166. function sb_sermon_init () {
  167. global $sermon_domain, $wpdb, $defaultMultiForm, $defaultSingleForm, $defaultStyle;
  168. $sermon_domain = 'sermon-browser';
  169. if (IS_MU) {
  170. load_plugin_textdomain($sermon_domain, '', 'sb-includes');
  171. } else {
  172. load_plugin_textdomain($sermon_domain, '', 'sermon-browser/sb-includes');
  173. }
  174. if (WPLANG != '')
  175. setlocale(LC_ALL, WPLANG.'.UTF-8');
  176. //Display the podcast if that's what's requested
  177. if (isset($_GET['podcast']))
  178. require('sb-includes/podcast.php');
  179. // Register custom CSS and javascript files
  180. wp_register_script('sb_64', SB_PLUGIN_URL.'/sb-includes/64.js', false, SB_CURRENT_VERSION);
  181. wp_register_script('sb_datepicker', SB_PLUGIN_URL.'/sb-includes/datePicker.js', array('jquery'), SB_CURRENT_VERSION);
  182. wp_register_style('sb_datepicker', SB_PLUGIN_URL.'/sb-includes/datepicker.css', false, SB_CURRENT_VERSION);
  183. if (get_option('permalink_structure') == '')
  184. wp_register_style('sb_style', trailingslashit(get_option('siteurl')).'?sb-style&', false, sb_get_option('style_date_modified'));
  185. else
  186. wp_register_style('sb_style', trailingslashit(get_option('siteurl')).'sb-style.css', false, sb_get_option('style_date_modified'));
  187. // Register [sermon] shortcode handler
  188. add_shortcode('sermons', 'sb_shortcode');
  189. // Attempt to set php.ini directives
  190. if (sb_return_kbytes(ini_get('upload_max_filesize'))<15360)
  191. ini_set('upload_max_filesize', '15M');
  192. if (sb_return_kbytes(ini_get('post_max_size'))<15360)
  193. ini_set('post_max_size', '15M');
  194. if (sb_return_kbytes(ini_get('memory_limit'))<49152)
  195. ini_set('memory_limit', '48M');
  196. if (intval(ini_get('max_input_time'))<600)
  197. ini_set('max_input_time','600');
  198. if (intval(ini_get('max_execution_time'))<600)
  199. ini_set('max_execution_time', '600');
  200. if (ini_get('file_uploads')<>'1')
  201. ini_set('file_uploads', '1');
  202. // Check whether upgrade required
  203. if (current_user_can('manage_options') && is_admin()) {
  204. if (get_option('sb_sermon_db_version'))
  205. $db_version = get_option('sb_sermon_db_version');
  206. else
  207. $db_version = sb_get_option('db_version');
  208. if ($db_version && $db_version != SB_DATABASE_VERSION) {
  209. require_once ('sb-includes/upgrade.php');
  210. sb_database_upgrade ($db_version);
  211. } elseif (!$db_version) {
  212. require ('sb-includes/sb-install.php');
  213. sb_install();
  214. }
  215. $sb_version = sb_get_option('code_version');
  216. if ($sb_version != SB_CURRENT_VERSION) {
  217. require_once ('sb-includes/upgrade.php');
  218. sb_version_upgrade ($sb_version, SB_CURRENT_VERSION);
  219. }
  220. }
  221. // Load shared (admin/frontend) features
  222. add_action ('save_post', 'update_podcast_url');
  223. // Check to see what functions are required, and only load what is needed
  224. if (stripos($_SERVER['REQUEST_URI'], '/wp-admin/') === FALSE) {
  225. require ('sb-includes/frontend.php');
  226. add_action('wp_head', 'sb_add_headers', 0);
  227. add_action('wp_head', 'wp_print_styles', 9);
  228. add_filter('wp_title', 'sb_page_title');
  229. if (defined('SAVEQUERIES') && SAVEQUERIES)
  230. add_action ('wp_footer', 'sb_footer_stats');
  231. } else {
  232. require ('sb-includes/admin.php');
  233. add_action ('admin_menu', 'sb_add_pages');
  234. add_action ('rightnow_end', 'sb_rightnow');
  235. add_action('admin_init', 'sb_add_admin_headers');
  236. add_filter('contextual_help', 'sb_add_contextual_help');
  237. if (defined('SAVEQUERIES') && SAVEQUERIES)
  238. add_action('admin_footer', 'sb_footer_stats');
  239. }
  240. }
  241. /**
  242. * Add Sermons menu and sub-menus in admin
  243. */
  244. function sb_add_pages() {
  245. global $sermon_domain;
  246. add_menu_page(__('Sermons', $sermon_domain), __('Sermons', $sermon_domain), 'edit_posts', __FILE__, 'sb_manage_sermons', SB_PLUGIN_URL.'/sb-includes/sb-icon.png');
  247. add_submenu_page(__FILE__, __('Sermons', $sermon_domain), __('Sermons', $sermon_domain), 'edit_posts', __FILE__, 'sb_manage_sermons');
  248. if (isset($_REQUEST['page']) && $_REQUEST['page'] == 'sermon-browser/new_sermon.php' && isset($_REQUEST['mid'])) {
  249. add_submenu_page(__FILE__, __('Edit Sermon', $sermon_domain), __('Edit Sermon', $sermon_domain), 'publish_posts', 'sermon-browser/new_sermon.php', 'sb_new_sermon');
  250. } else {
  251. add_submenu_page(__FILE__, __('Add Sermon', $sermon_domain), __('Add Sermon', $sermon_domain), 'publish_posts', 'sermon-browser/new_sermon.php', 'sb_new_sermon');
  252. }
  253. add_submenu_page(__FILE__, __('Files', $sermon_domain), __('Files', $sermon_domain), 'upload_files', 'sermon-browser/files.php', 'sb_files');
  254. add_submenu_page(__FILE__, __('Preachers', $sermon_domain), __('Preachers', $sermon_domain), 'manage_categories', 'sermon-browser/preachers.php', 'sb_manage_preachers');
  255. add_submenu_page(__FILE__, __('Series &amp; Services', $sermon_domain), __('Series &amp; Services', $sermon_domain), 'manage_categories', 'sermon-browser/manage.php', 'sb_manage_everything');
  256. add_submenu_page(__FILE__, __('Options', $sermon_domain), __('Options', $sermon_domain), 'manage_options', 'sermon-browser/options.php', 'sb_options');
  257. add_submenu_page(__FILE__, __('Templates', $sermon_domain), __('Templates', $sermon_domain), 'manage_options', 'sermon-browser/templates.php', 'sb_templates');
  258. add_submenu_page(__FILE__, __('Uninstall', $sermon_domain), __('Uninstall', $sermon_domain), 'edit_plugins', 'sermon-browser/uninstall.php', 'sb_uninstall');
  259. add_submenu_page(__FILE__, __('Help', $sermon_domain), __('Help', $sermon_domain), 'edit_posts', 'sermon-browser/help.php', 'sb_help');
  260. }
  261. /**
  262. * Converts php.ini mega- or giga-byte numbers into kilobytes
  263. *
  264. * @param string $val
  265. * @return integer
  266. */
  267. function sb_return_kbytes($val) {
  268. $val = trim($val);
  269. $last = strtolower($val[strlen($val)-1]);
  270. switch($last) {
  271. case 'g':
  272. $val *= 1024;
  273. case 'm':
  274. $val *= 1024;
  275. }
  276. return intval($val);
  277. }
  278. /**
  279. * Count download stats for sermon
  280. *
  281. * Returns the number of plays for a particular file
  282. *
  283. * @param integer $sermonid
  284. * @return integer
  285. */
  286. function sb_sermon_stats($sermonid) {
  287. global $wpdb;
  288. $stats = $wpdb->get_var("SELECT SUM(count) FROM ".$wpdb->prefix."sb_stuff WHERE sermon_id=".$sermonid);
  289. if ($stats > 0)
  290. return $stats;
  291. }
  292. /**
  293. * Updates podcast URL in wp_options
  294. *
  295. * Function required if permalinks changed or [sermons] added to a different page
  296. */
  297. function update_podcast_url () {
  298. global $wp_rewrite;
  299. $existing_url = sb_get_option('podcast_url');
  300. if (substr($existing_url, 0, strlen(get_bloginfo('wpurl'))) == get_bloginfo('wpurl')) {
  301. if (sb_display_url(TRUE)=="") {
  302. sb_update_option('podcast_url', get_bloginfo('wpurl').sb_query_char(false).'podcast');
  303. } else {
  304. sb_update_option('podcast_url', sb_display_url().sb_query_char(false).'podcast');
  305. }
  306. }
  307. }
  308. /**
  309. * Returns occassionally requested default values
  310. *
  311. * Not defined as constants to save memory
  312. * @param string $default_type
  313. * @return mixed
  314. */
  315. function sb_get_default ($default_type) {
  316. global $sermon_domain;
  317. switch ($default_type) {
  318. case 'sermon_path':
  319. $upload_path = wp_upload_dir();
  320. $upload_path = $upload_path['basedir'];
  321. if (substr($upload_path, 0, strlen(ABSPATH)) == ABSPATH)
  322. $upload_path = substr($upload_path, strlen(ABSPATH));
  323. return trailingslashit($upload_path).'sermons/';
  324. case 'attachment_url':
  325. $upload_dir = wp_upload_dir();
  326. $upload_dir = $upload_dir['baseurl'];
  327. return trailingslashit($upload_dir).'sermons/';
  328. case 'bible_books':
  329. return array(__('Genesis', $sermon_domain), __('Exodus', $sermon_domain), __('Leviticus', $sermon_domain), __('Numbers', $sermon_domain), __('Deuteronomy', $sermon_domain), __('Joshua', $sermon_domain), __('Judges', $sermon_domain), __('Ruth', $sermon_domain), __('1 Samuel', $sermon_domain), __('2 Samuel', $sermon_domain), __('1 Kings', $sermon_domain), __('2 Kings', $sermon_domain), __('1 Chronicles', $sermon_domain), __('2 Chronicles',$sermon_domain), __('Ezra', $sermon_domain), __('Nehemiah', $sermon_domain), __('Esther', $sermon_domain), __('Job', $sermon_domain), __('Psalm', $sermon_domain), __('Proverbs', $sermon_domain), __('Ecclesiastes', $sermon_domain), __('Song of Solomon', $sermon_domain), __('Isaiah', $sermon_domain), __('Jeremiah', $sermon_domain), __('Lamentations', $sermon_domain), __('Ezekiel', $sermon_domain), __('Daniel', $sermon_domain), __('Hosea', $sermon_domain), __('Joel', $sermon_domain), __('Amos', $sermon_domain), __('Obadiah', $sermon_domain), __('Jonah', $sermon_domain), __('Micah', $sermon_domain), __('Nahum', $sermon_domain), __('Habakkuk', $sermon_domain), __('Zephaniah', $sermon_domain), __('Haggai', $sermon_domain), __('Zechariah', $sermon_domain), __('Malachi', $sermon_domain), __('Matthew', $sermon_domain), __('Mark', $sermon_domain), __('Luke', $sermon_domain), __('John', $sermon_domain), __('Acts', $sermon_domain), __('Romans', $sermon_domain), __('1 Corinthians', $sermon_domain), __('2 Corinthians', $sermon_domain), __('Galatians', $sermon_domain), __('Ephesians', $sermon_domain), __('Philippians', $sermon_domain), __('Colossians', $sermon_domain), __('1 Thessalonians', $sermon_domain), __('2 Thessalonians', $sermon_domain), __('1 Timothy', $sermon_domain), __('2 Timothy', $sermon_domain), __('Titus', $sermon_domain), __('Philemon', $sermon_domain), __('Hebrews', $sermon_domain), __('James', $sermon_domain), __('1 Peter', $sermon_domain), __('2 Peter', $sermon_domain), __('1 John', $sermon_domain), __('2 John', $sermon_domain), __('3 John', $sermon_domain), __('Jude', $sermon_domain), __('Revelation', $sermon_domain));
  330. case 'eng_bible_books':
  331. return array('Genesis', 'Exodus', 'Leviticus', 'Numbers', 'Deuteronomy', 'Joshua', 'Judges', 'Ruth', '1 Samuel', '2 Samuel', '1 Kings', '2 Kings', '1 Chronicles', '2 Chronicles', 'Ezra', 'Nehemiah', 'Esther', 'Job', 'Psalm', 'Proverbs', 'Ecclesiastes', 'Song of Solomon', 'Isaiah', 'Jeremiah', 'Lamentations', 'Ezekiel', 'Daniel', 'Hosea', 'Joel', 'Amos', 'Obadiah', 'Jonah', 'Micah', 'Nahum', 'Habakkuk', 'Zephaniah', 'Haggai', 'Zechariah', 'Malachi', 'Matthew', 'Mark', 'Luke', 'John', 'Acts', 'Romans', '1 Corinthians', '2 Corinthians', 'Galatians', 'Ephesians', 'Philippians', 'Colossians', '1 Thessalonians', '2 Thessalonians', '1 Timothy', '2 Timothy', 'Titus', 'Philemon', 'Hebrews', 'James', '1 Peter', '2 Peter', '1 John', '2 John', '3 John', 'Jude', 'Revelation');
  332. }
  333. }
  334. /**
  335. * Returns true if sermons are displayed on the current page
  336. *
  337. * @return bool
  338. */
  339. function sb_display_front_end() {
  340. global $wpdb, $post;
  341. $pageid = $wpdb->get_var("SELECT ID FROM {$wpdb->posts} WHERE post_content LIKE '%[sermons%' AND (post_status = 'publish' OR post_status = 'private') AND ID={$post->ID} AND post_date < NOW();");
  342. if ($pageid === NULL)
  343. return FALSE;
  344. else
  345. return TRUE;
  346. }
  347. /**
  348. * Get the URL of the main sermons page
  349. *
  350. * @return string
  351. */
  352. function sb_display_url() {
  353. global $wpdb, $post, $sb_display_url;
  354. if ($sb_display_url == '') {
  355. $pageid = $wpdb->get_var("SELECT ID FROM {$wpdb->posts} WHERE post_content LIKE '%[sermons]%' AND (post_status = 'publish' OR post_status = 'private') AND post_date < NOW();");
  356. if (!$pageid)
  357. $pageid = $wpdb->get_var("SELECT ID FROM {$wpdb->posts} WHERE post_content LIKE '%[sermons %' AND (post_status = 'publish' OR post_status = 'private') AND post_date < NOW();");
  358. if (!$pageid)
  359. return '#';
  360. $sb_display_url = get_permalink($pageid);
  361. if ($sb_display_url == get_bloginfo('wpurl') || $sb_display_url == '') // Hack to force true permalink even if page used for front page.
  362. $sb_display_url = get_bloginfo('wpurl').'/?page_id='.$pageid;
  363. }
  364. return $sb_display_url;
  365. }
  366. /**
  367. * Fix to ensure AudioPlayer v2 and AudioPlayer v1 both work
  368. */
  369. if (!function_exists('ap_insert_player_widgets') && function_exists('insert_audio_player')) {
  370. function ap_insert_player_widgets($params) {
  371. return insert_audio_player($params);
  372. }
  373. }
  374. /**
  375. * Adds database statistics to the HTML comments
  376. *
  377. * Requires define('SAVEQUERIES', true) in wp-config.php
  378. * Useful for diagnostics
  379. */
  380. function sb_footer_stats() {
  381. global $wpdb;
  382. echo '<!-- ';
  383. echo($wpdb->num_queries.' queries. '.timer_stop().' seconds.');
  384. echo chr(13);
  385. print_r($wpdb->queries);
  386. echo chr(13);
  387. echo ' -->';
  388. }
  389. /**
  390. * Returns the correct string to join the sermonbrowser parameters to the existing URL
  391. *
  392. * @param boolean $return_entity
  393. * @return string (either '?', '&', or '&amp;')
  394. */
  395. function sb_query_char ($return_entity = true) {
  396. if (strpos(sb_display_url(), '?')===FALSE)
  397. return '?';
  398. else
  399. if ($return_entity)
  400. return '&amp;';
  401. else
  402. return '&';
  403. }
  404. /**
  405. * Create the shortcode handler
  406. *
  407. * Standard shortcode handler that inserts the sermonbrowser output into the post/page
  408. *
  409. * @param array $atts
  410. * @param string $content
  411. * @return string
  412. */
  413. function sb_shortcode($atts, $content=null) {
  414. global $wpdb, $record_count, $sermon_domain;
  415. ob_start();
  416. $atts = shortcode_atts(array(
  417. 'filter' => sb_get_option('filter_type'),
  418. 'filterhide' => sb_get_option('filter_hide'),
  419. 'id' => isset($_REQUEST['sermon_id']) ? $_REQUEST['sermon_id'] : '',
  420. 'preacher' => isset($_REQUEST['preacher']) ? $_REQUEST['preacher'] : '',
  421. 'series' => isset($_REQUEST['series']) ? $_REQUEST['series'] : '',
  422. 'book' => isset($_REQUEST['book']) ? $_REQUEST['book'] : '',
  423. 'service' => isset($_REQUEST['service']) ? $_REQUEST['service'] : '',
  424. 'date' => isset($_REQUEST['date']) ? $_REQUEST['date'] : '',
  425. 'enddate' => isset($_REQUEST['enddate']) ? $_REQUEST['enddate'] : '',
  426. 'tag' => isset($_REQUEST['stag']) ? $_REQUEST['stag'] : '',
  427. 'title' => isset($_REQUEST['title']) ? $_REQUEST['title'] : '',
  428. ), $atts);
  429. if ($atts['id'] != '') {
  430. if (strtolower($atts['id']) == 'latest') {
  431. $atts['id'] = '';
  432. $query = $wpdb->get_results(sb_create_multi_sermon_query($atts, array(), 1, 1));
  433. $atts['id'] = $query[0]->id;
  434. }
  435. $sermon = sb_get_single_sermon((int) $atts['id']);
  436. if ($sermon)
  437. eval('?>'.sb_get_option('single_output'));
  438. else {
  439. echo "<div class=\"sermon-browser-results\"><span class=\"error\">";
  440. _e ('No sermons found.', $sermon_domain);
  441. echo "</span></div>";
  442. }
  443. } else {
  444. if (isset($_REQUEST['sortby']))
  445. $sort_criteria = $_REQUEST['sortby'];
  446. else
  447. $sort_criteria = 'm.datetime';
  448. if (isset($_REQUEST['dir']))
  449. $dir = $_REQUEST['dir'];
  450. elseif ($sort_criteria == 'm.datetime')
  451. $dir = 'desc';
  452. else
  453. $dir = 'asc';
  454. $sort_order = array('by' => $sort_criteria, 'dir' => $dir);
  455. if (isset($_REQUEST['page']))
  456. $page = $_REQUEST['page'];
  457. else
  458. $page = 1;
  459. $hide_empty = sb_get_option('hide_no_attachments');
  460. $sermons = sb_get_sermons($atts, $sort_order, $page, 0, $hide_empty);
  461. $output = '?>'.sb_get_option('search_output');
  462. eval($output);
  463. }
  464. $content = ob_get_contents();
  465. ob_end_clean();
  466. return $content;
  467. }
  468. /**
  469. * Registers the Sermon Browser widgets
  470. */
  471. function sb_widget_sermon_init() {
  472. global $sermon_domain;
  473. //Sermons Widget
  474. if (!$options = sb_get_option('sermons_widget_options'))
  475. $options = array();
  476. $widget_ops = array('classname' => 'sermon', 'description' => __('Display a list of recent sermons.', $sermon_domain));
  477. $control_ops = array('width' => 400, 'height' => 350, 'id_base' => 'sermon');
  478. $name = __('Sermons', $sermon_domain);
  479. $registered = false;
  480. foreach (array_keys($options) as $o) {
  481. if (!isset($options[$o]['limit']))
  482. continue;
  483. $id = "sermon-$o";
  484. $registered = true;
  485. wp_register_sidebar_widget($id, $name, 'sb_widget_sermon_wrapper', $widget_ops, array('number' => $o));
  486. wp_register_widget_control($id, $name, 'sb_widget_sermon_control', $control_ops, array('number' => $o));
  487. }
  488. if (!$registered) {
  489. wp_register_sidebar_widget('sermon-1', $name, 'sb_widget_sermon_wrapper', $widget_ops, array('number' => -1));
  490. wp_register_widget_control('sermon-1', $name, 'sb_widget_sermon_control', $control_ops, array('number' => -1));
  491. }
  492. //Tags Widget
  493. wp_register_sidebar_widget('sermon-browser-tags', __('Sermon Browser tags', $sermon_domain), 'sb_widget_tag_cloud_wrapper');
  494. //Most popular widget
  495. $name = __('Most popular sermons', $sermon_domain);
  496. $description = __('Display a list of the most popular sermons, series or preachers.', $sermon_domain);
  497. $widget_ops = array('classname' => 'sermon-browser-popular', 'description' => $description);
  498. $control_ops = array('width' => 400, 'height' => 350, 'id_base' => 'sermon-browser-popular');
  499. wp_register_sidebar_widget( 'sermon-browser-popular', $name, 'sb_widget_popular_wrapper', $widget_ops);
  500. wp_register_widget_control( 'sermon-browser-popular', $name, 'sb_widget_popular_control', $control_ops);
  501. }
  502. /**
  503. * Wrapper for sb_widget_sermon in frontend.php
  504. *
  505. * Allows main widget functionality to be in the frontend package, whilst still allowing widgets to be modified in admin
  506. * @param array $args
  507. * @param integer $widget_args
  508. */
  509. function sb_widget_sermon_wrapper ($args, $widget_args = 1) {
  510. require_once ('sb-includes/frontend.php');
  511. sb_widget_sermon($args, $widget_args);
  512. }
  513. /**
  514. * Wrapper for sb_widget_tag_cloud in frontend.php
  515. *
  516. * Allows main widget functionality to be in the frontend package, whilst still allowing widgets to be modified in admin
  517. * @param array $args
  518. */
  519. function sb_widget_tag_cloud_wrapper ($args) {
  520. require_once ('sb-includes/frontend.php');
  521. sb_widget_tag_cloud ($args);
  522. }
  523. /**
  524. * Wrapper for sb_widget_popular in frontend.php
  525. *
  526. * Allows main widget functionality to be in the frontend package, whilst still allowing widgets to be modified in admin
  527. * @param array $args
  528. */
  529. function sb_widget_popular_wrapper ($args) {
  530. require_once ('sb-includes/frontend.php');
  531. sb_widget_popular ($args);
  532. }
  533. /**
  534. * Optimised replacement for get_option
  535. *
  536. * Returns any of the sermonbrowser options from one row of the database
  537. * Large options (e.g. the template) are stored on additional rows by this function
  538. * @param string $type
  539. * @return mixed
  540. */
  541. function sb_get_option($type) {
  542. global $sermonbrowser_options;
  543. $special_options = sb_special_option_names();
  544. if (in_array($type, $special_options)) {
  545. return stripslashes(base64_decode(get_option("sermonbrowser_{$type}")));
  546. } else {
  547. if (!$sermonbrowser_options) {
  548. $options = get_option('sermonbrowser_options');
  549. if ($options === FALSE)
  550. return FALSE;
  551. $sermonbrowser_options = unserialize(base64_decode($options));
  552. if ($sermonbrowser_options === FALSE)
  553. wp_die ('Failed to get SermonBrowser options '.base64_decode(get_option('sermonbrowser_options')));
  554. }
  555. if (isset($sermonbrowser_options[$type]))
  556. return $sermonbrowser_options[$type];
  557. else
  558. return '';
  559. }
  560. }
  561. /**
  562. * Optimised replacement for update_option
  563. *
  564. * Stores all of sermonbrowser options on one row of the database
  565. * Large options (e.g. the template) are stored on additional rows by this function
  566. * @param string $type
  567. * @param mixed $val
  568. * @return bool
  569. */
  570. function sb_update_option($type, $val) {
  571. global $sermonbrowser_options;
  572. $special_options = sb_special_option_names();
  573. if (in_array($type, $special_options))
  574. return update_option ("sermonbrowser_{$type}", base64_encode($val));
  575. else {
  576. if (!$sermonbrowser_options) {
  577. $options = get_option('sermonbrowser_options');
  578. if ($options !== FALSE) {
  579. $sermonbrowser_options = unserialize(base64_decode($options));
  580. if ($sermonbrowser_options === FALSE)
  581. wp_die ('Failed to get SermonBrowser options '.base64_decode(get_option('sermonbrowser_options')));
  582. }
  583. }
  584. if (!isset($sermonbrowser_options[$type]) || $sermonbrowser_options[$type] !== $val) {
  585. $sermonbrowser_options[$type] = $val;
  586. return update_option('sermonbrowser_options', base64_encode(serialize($sermonbrowser_options)));
  587. } else
  588. return false;
  589. }
  590. }
  591. /**
  592. * Returns which options need to be stored in individual base64 format (i.e. potentially large strings)
  593. *
  594. * @return array
  595. */
  596. function sb_special_option_names() {
  597. return array ('single_template', 'single_output', 'search_template', 'search_output', 'css_style');
  598. }
  599. /**
  600. * Recursive mkdir function
  601. *
  602. * @param string $pathname
  603. * @param string $mode
  604. * return bool
  605. */
  606. function sb_mkdir($pathname, $mode=0777) {
  607. is_dir(dirname($pathname)) || sb_mkdir(dirname($pathname), $mode);
  608. @mkdir($pathname, $mode);
  609. return @chmod($pathname, $mode);
  610. }
  611. /**
  612. * Defines a number of constants used throughout the plugin
  613. */
  614. function sb_define_constants() {
  615. $directories = explode(DIRECTORY_SEPARATOR,dirname(__FILE__));
  616. if ($directories[count($directories)-1] == 'mu-plugins') {
  617. define('IS_MU', TRUE);
  618. } else {
  619. define('IS_MU', FALSE);
  620. }
  621. if ( !defined('WP_CONTENT_URL') )
  622. define( 'WP_CONTENT_URL', trailingslashit(get_option('siteurl')) . 'wp-content');
  623. $plugin_dir = $directories[count($directories)-1];
  624. if (IS_MU)
  625. define ('SB_PLUGIN_URL', WP_CONTENT_URL.'/'.$plugin_dir);
  626. else
  627. define ('SB_PLUGIN_URL', rtrim(WP_CONTENT_URL.'/plugins/'.plugin_basename(dirname(__FILE__)), '/'));
  628. define ('SB_WP_PLUGIN_DIR', sb_sanitise_path(WP_PLUGIN_DIR));
  629. define ('SB_WP_CONTENT_DIR', sb_sanitise_path(WP_CONTENT_DIR));
  630. define ('SB_ABSPATH', sb_sanitise_path(ABSPATH));
  631. define ('GETID3_INCLUDEPATH', SB_WP_PLUGIN_DIR.'/'.$plugin_dir.'/sb-includes/getid3/');
  632. define ('GETID3_HELPERAPPSDIR', GETID3_INCLUDEPATH);
  633. }
  634. /**
  635. * Returns list of bible books from the database
  636. *
  637. * @return array
  638. */
  639. function sb_get_bible_books () {
  640. global $wpdb;
  641. return $wpdb->get_col("SELECT name FROM {$wpdb->prefix}sb_books order by id");
  642. }
  643. /**
  644. * Get multiple sermons from the database
  645. *
  646. * Uses sb_create_multi_sermon_query to general the SQL statement
  647. * @param array $filter
  648. * @param string $order
  649. * @param integer $page
  650. * @param integer $limit
  651. * @global integer record_count
  652. * @return array
  653. */
  654. function sb_get_sermons($filter, $order, $page = 1, $limit = 0, $hide_empty = false) {
  655. global $wpdb, $record_count;
  656. if ($limit == 0)
  657. $limit = sb_get_option('sermons_per_page');
  658. $query = $wpdb->get_results(sb_create_multi_sermon_query($filter, $order, $page, $limit, $hide_empty));
  659. $record_count = $wpdb->get_var("SELECT FOUND_ROWS()");
  660. return $query;
  661. }
  662. /**
  663. * Create SQL query for returning multiple sermons
  664. *
  665. * @param array $filter
  666. * @param string $order
  667. * @param integer $page
  668. * @param integer $limit
  669. * @return string SQL query
  670. */
  671. function sb_create_multi_sermon_query ($filter, $order, $page = 1, $limit = 0, $hide_empty = false) {
  672. global $wpdb;
  673. $default_filter = array(
  674. 'title' => '',
  675. 'preacher' => 0,
  676. 'date' => '',
  677. 'enddate' => '',
  678. 'series' => 0,
  679. 'service' => 0,
  680. 'book' => '',
  681. 'tag' => '',
  682. 'id' => '',
  683. );
  684. $default_order = array(
  685. 'by' => 'm.datetime',
  686. 'dir' => 'desc',
  687. );
  688. $bs = '';
  689. $filter = array_merge($default_filter, (array)$filter);
  690. $order = array_merge($default_order, (array)$order);
  691. $page = (int) $page;
  692. $cond = '1=1 ';
  693. if ($filter['title'] != '') {
  694. $cond .= "AND (m.title LIKE '%" . $wpdb->escape($filter['title']) . "%' OR m.description LIKE '%" . $wpdb->escape($filter['title']). "%' OR t.name LIKE '%" . $wpdb->escape($filter['title']) . "%') ";
  695. }
  696. if ($filter['preacher'] != 0) {
  697. $cond .= 'AND m.preacher_id = ' . (int) $filter['preacher'] . ' ';
  698. }
  699. if ($filter['date'] != '') {
  700. $cond .= 'AND m.datetime >= "' . $wpdb->escape($filter['date']) . '" ';
  701. }
  702. if ($filter['enddate'] != '') {
  703. $cond .= 'AND m.datetime <= "' . $wpdb->escape($filter['enddate']) . '" ';
  704. }
  705. if ($filter['series'] != 0) {
  706. $cond .= 'AND m.series_id = ' . (int) $filter['series'] . ' ';
  707. }
  708. if ($filter['service'] != 0) {
  709. $cond .= 'AND m.service_id = ' . (int) $filter['service'] . ' ';
  710. }
  711. if ($filter['book'] != '') {
  712. $cond .= 'AND bs.book_name = "' . $wpdb->escape($filter['book']) . '" ';
  713. } else {
  714. $bs = "AND bs.order = 0 AND bs.type= 'start' ";
  715. }
  716. if ($filter['tag'] != '') {
  717. $cond .= "AND t.name LIKE '%" . $wpdb->escape($filter['tag']) . "%' ";
  718. }
  719. if ($filter['id'] != '') {
  720. $cond .= "AND m.id LIKE '" . $wpdb->escape($filter['id']) . "' ";
  721. }
  722. if ($hide_empty) {
  723. $cond .= "AND stuff.name != '' ";
  724. }
  725. $offset = $limit * ($page - 1);
  726. if ($order['by'] == 'b.id' ) {
  727. $order['by'] = 'b.id '.$order['dir'].', bs.chapter '.$order['dir'].', bs.verse';
  728. }
  729. return "SELECT SQL_CALC_FOUND_ROWS DISTINCT m.id, m.title, m.description, m.datetime, m.time, m.start, m.end, p.id as pid, p.name as preacher, p.description as preacher_description, p.image, s.id as sid, s.name as service, ss.id as ssid, ss.name as series
  730. FROM {$wpdb->prefix}sb_sermons as m
  731. LEFT JOIN {$wpdb->prefix}sb_preachers as p ON m.preacher_id = p.id
  732. LEFT JOIN {$wpdb->prefix}sb_services as s ON m.service_id = s.id
  733. LEFT JOIN {$wpdb->prefix}sb_series as ss ON m.series_id = ss.id
  734. LEFT JOIN {$wpdb->prefix}sb_books_sermons as bs ON bs.sermon_id = m.id $bs
  735. LEFT JOIN {$wpdb->prefix}sb_books as b ON bs.book_name = b.name
  736. LEFT JOIN {$wpdb->prefix}sb_sermons_tags as st ON st.sermon_id = m.id
  737. LEFT JOIN {$wpdb->prefix}sb_tags as t ON t.id = st.tag_id
  738. LEFT JOIN {$wpdb->prefix}sb_stuff as stuff ON stuff.sermon_id = m.id
  739. WHERE {$cond} ORDER BY ". $order['by'] . " " . $order['dir'] . " LIMIT " . $offset . ", " . $limit;
  740. }
  741. /**
  742. * Returns the default time for a particular service
  743. *
  744. * @param integer $service (id in database)
  745. * @return string (service time)
  746. */
  747. function sb_default_time($service) {
  748. global $wpdb;
  749. $sermon_time = $wpdb->get_var("SELECT time FROM {$wpdb->prefix}sb_services WHERE id='{$service}'");
  750. if (isset($sermon_time)) {
  751. return $sermon_time;
  752. } else {
  753. return "00:00";
  754. }
  755. }
  756. /**
  757. * Gets attachments from database
  758. *
  759. * @param integer $sermon (id in database)
  760. * @param boolean $mp3_only (if true will only return MP3 files)
  761. * @return array
  762. */
  763. function sb_get_stuff($sermon, $mp3_only = FALSE) {
  764. global $wpdb;
  765. if ($mp3_only) {
  766. $stuff = $wpdb->get_results("SELECT f.type, f.name FROM {$wpdb->prefix}sb_stuff as f WHERE sermon_id = $sermon->id AND name LIKE '%.mp3' ORDER BY id desc");
  767. } else {
  768. $stuff = $wpdb->get_results("SELECT f.type, f.name FROM {$wpdb->prefix}sb_stuff as f WHERE sermon_id = $sermon->id ORDER BY id desc");
  769. }
  770. $file = $url = $code = array();
  771. foreach ($stuff as $cur)
  772. ${$cur->type}[] = $cur->name;
  773. return array(
  774. 'Files' => $file,
  775. 'URLs' => $url,
  776. 'Code' => $code,
  777. );
  778. }
  779. /**
  780. * Increases the download count for file attachments
  781. *
  782. * Increases the download count for the file $stuff_name
  783. *
  784. * @param string $stuff_name
  785. */
  786. function sb_increase_download_count ($stuff_name) {
  787. if (function_exists('current_user_can')&&!(current_user_can('edit_posts')|current_user_can('publish_posts'))) {
  788. global $wpdb;
  789. $wpdb->query("UPDATE ".$wpdb->prefix."sb_stuff SET COUNT=COUNT+1 WHERE name='".$wpdb->escape($stuff_name)."'");
  790. }
  791. }
  792. /**
  793. * Outputs a remote or local file
  794. *
  795. * @param string $filename
  796. * @return bool success or failure
  797. */
  798. function output_file($filename) {
  799. $handle = fopen($filename, 'rb');
  800. if ($handle === false)
  801. return false;
  802. if (ob_get_level() == 0)
  803. ob_start();
  804. while (!feof($handle)) {
  805. set_time_limit(ini_get('max_execution_time'));
  806. $buffer = fread($handle, 1048576);
  807. echo $buffer;
  808. ob_flush();
  809. flush();
  810. }
  811. return fclose($handle);
  812. }
  813. /**
  814. * Sanitizes Windows paths
  815. */
  816. function sb_sanitise_path ($path) {
  817. $path = str_replace('\\','/',$path);
  818. $path = preg_replace('|/+|','/', $path);
  819. return $path;
  820. }
  821. ?>