PageRenderTime 61ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

/wp-content/plugins/ajax-event-calendar/ajax-event-calendar.php

https://bitbucket.org/nathancorbier/wastark.com
PHP | 1801 lines | 1501 code | 187 blank | 113 comment | 144 complexity | 1f0cf6b0ae9c577e95405dbda7a12cb2 MD5 | raw file
Possible License(s): BSD-3-Clause

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /*
  3. Plugin Name: Ajax Event Calendar
  4. Plugin URI: http://wordpress.org/extend/plugins/ajax-event-calendar/
  5. Description: A fully localized community calendar that allows authorized users to manage events in custom categories.
  6. Version: 1.0.4
  7. Author: Eran Miller
  8. Author URI: http://eranmiller.com
  9. License: GPL2
  10. */
  11. /* Copyright 2011 Eran Miller <email: plugins@eranmiller.com>
  12. This program is free software; you can redistribute it and/or modify
  13. it under the terms of the GNU General Public License, version 2, as
  14. published by the Free Software Foundation.
  15. This program is distributed in the hope that it will be useful,
  16. but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. GNU General Public License for more details.
  19. You should have received a copy of the GNU General Public License
  20. along with this program; if not, write to the Free Software
  21. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  22. */
  23. // disallow direct access to file
  24. if (basename($_SERVER['PHP_SELF']) == basename(__FILE__)) {
  25. die('Sorry, but you cannot access this page directly.');
  26. }
  27. if (version_compare(PHP_VERSION, '5', '<')) {
  28. $out = "<div id='message' style='width:94%' class='message error'>";
  29. $out .= sprintf("<p><strong>Your PHP version is '%s'.<br>The Ajax Event Calendar WordPress plugin requires PHP 5 or higher.</strong></p><p>Ask your web host how to enable PHP 5 on your site.</p>", PHP_VERSION);
  30. $out .= "</div>";
  31. print $out;
  32. }
  33. define('AEC_MENU_POSITION', null); //previously 30
  34. define('AEC_VERSION', '1.0.4');
  35. define('AEC_FILE', basename(__FILE__));
  36. define('AEC_NAME', str_replace('.php', '', AEC_FILE));
  37. define('AEC_PATH', plugin_dir_path(__FILE__));
  38. define('AEC_URL', plugin_dir_url(__FILE__));
  39. define('AEC_EVENT_TABLE', 'aec_event');
  40. define('AEC_CATEGORY_TABLE', 'aec_event_category');
  41. define('AEC_HOMEPAGE', 'http://wordpress.org/extend/plugins/' . AEC_NAME . '/');
  42. define('AEC_WP_DATE_FORMAT', get_option('date_format'));
  43. define('AEC_WP_TIME_FORMAT', get_option('time_format'));
  44. define('AEC_DB_DATETIME_FORMAT', 'Y-m-d H:i:s');
  45. define('AEC_LOCALE', substr(get_locale(), 0, 2)); // for javascript localization scripts
  46. // if uncommented, overrides the location of the WP error log to the AEC plugin root
  47. // @ini_set('error_log', AEC_PATH . 'aec_debug.log');
  48. if (!class_exists('ajax_event_calendar')) {
  49. class ajax_event_calendar {
  50. private $required_fields = array();
  51. private $shortcode_params = array();
  52. private $admin_messages = array();
  53. private $plugin_defaults = array(
  54. 'filter_label' => 'Show Type',
  55. 'limit' => '0',
  56. 'show_weekends' => '1',
  57. 'show_map_link' => '1',
  58. 'menu' => '1',
  59. 'make_links' => '0',
  60. 'popup_links' => '1',
  61. 'step_interval' => '30',
  62. 'addy_format' => '0',
  63. 'scroll' => '1',
  64. 'title' => '2',
  65. 'venue' => '1',
  66. 'address' => '2',
  67. 'city' => '2',
  68. 'state' => '2',
  69. 'zip' => '2',
  70. 'country' => '1',
  71. 'link' => '1',
  72. 'description' => '2',
  73. 'contact' => '2',
  74. 'contact_info' => '2',
  75. 'accessible' => '0',
  76. 'rsvp' => '0',
  77. 'reset' => '0'
  78. );
  79. function __construct() {
  80. add_action('plugins_loaded', array($this, 'version_patches'));
  81. add_action('init', array($this, 'localize_plugin'));
  82. add_action('admin_menu', array($this, 'render_admin_menu'));
  83. add_action('admin_init', array($this, 'admin_options_initialize'));
  84. add_action('wp_print_styles', array($this, 'calendar_styles'));
  85. add_action('wp_print_scripts', array($this, 'frontend_calendar_scripts'));
  86. add_action('delete_user', array($this, 'delete_events_by_user'));
  87. add_action('admin_notices', array(&$this, 'admin_alert'));
  88. // ajax hooks
  89. add_action('wp_ajax_nopriv_get_events', array($this, 'render_calendar_events'));
  90. add_action('wp_ajax_get_events', array($this, 'render_calendar_events'));
  91. add_action('wp_ajax_nopriv_get_event', array($this, 'render_frontend_modal'));
  92. add_action('wp_ajax_get_event', array($this, 'render_frontend_modal'));
  93. add_action('wp_ajax_admin_event', array($this, 'render_admin_modal'));
  94. add_action('wp_ajax_add_event', array($this, 'add_event'));
  95. add_action('wp_ajax_copy_event', array($this, 'copy_event'));
  96. add_action('wp_ajax_update_event', array($this, 'update_event'));
  97. add_action('wp_ajax_delete_event', array($this, 'delete_event'));
  98. add_action('wp_ajax_move_event', array($this, 'move_event'));
  99. add_action('wp_ajax_add_category', array($this, 'add_category'));
  100. add_action('wp_ajax_update_filter_label', array($this, 'update_filter_label'));
  101. add_action('wp_ajax_update_category', array($this, 'update_category'));
  102. add_action('wp_ajax_delete_category', array($this, 'confirm_delete_category'));
  103. add_action('wp_ajax_reassign_category', array($this, 'reassign_category'));
  104. // wordpress overrides
  105. add_filter('manage_users_columns', array($this, 'add_events_column'));
  106. add_filter('manage_users_custom_column', array($this, 'add_events_column_data'), 10, 3);
  107. add_filter('plugin_action_links', array($this, 'settings_link'), 10, 2);
  108. add_filter('option_page_capability_aec_plugin_options', array($this, 'set_option_page_capability'));
  109. add_shortcode('calendar', array($this, 'render_shortcode_calendar'));
  110. add_shortcode('eventlist', array($this, 'render_shortcode_eventlist'));
  111. // activate shortcode in text widgets
  112. add_filter('widget_text', 'shortcode_unautop');
  113. add_filter('widget_text', 'do_shortcode');
  114. }
  115. function install() {
  116. require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
  117. global $wpdb;
  118. if ($wpdb->get_var('SHOW TABLES LIKE "' . $wpdb->prefix . AEC_EVENT_TABLE . '"') != $wpdb->prefix . AEC_EVENT_TABLE) {
  119. $sql = 'CREATE TABLE ' . $wpdb->prefix . AEC_EVENT_TABLE . ' (
  120. id BIGINT(20) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
  121. user_id INT(10) UNSIGNED NOT NULL,
  122. title VARCHAR(100) NOT NULL,
  123. start DATETIME NOT NULL,
  124. end DATETIME NOT NULL,
  125. repeat_freq TINYINT(4) UNSIGNED DEFAULT 0,
  126. repeat_int TINYINT(4) UNSIGNED DEFAULT 0,
  127. repeat_end DATE,
  128. allDay TINYINT(1) UNSIGNED DEFAULT 0,
  129. category_id TINYINT(4) UNSIGNED NOT NULL,
  130. description VARCHAR(2500),
  131. link VARCHAR(2000),
  132. venue VARCHAR(100),
  133. address VARCHAR(100),
  134. city VARCHAR(50),
  135. state VARCHAR(50),
  136. zip VARCHAR(10),
  137. country VARCHAR(50),
  138. contact VARCHAR(50),
  139. contact_info VARCHAR(50),
  140. access TINYINT(1) UNSIGNED DEFAULT 0,
  141. rsvp TINYINT(1) UNSIGNED DEFAULT 0)
  142. CHARSET=utf8;';
  143. dbDelta($sql);
  144. }
  145. if ($wpdb->get_var('SHOW TABLES LIKE "' . $wpdb->prefix . AEC_CATEGORY_TABLE . '"') != $wpdb->prefix . AEC_CATEGORY_TABLE) {
  146. $sql = 'CREATE TABLE ' . $wpdb->prefix . AEC_CATEGORY_TABLE . ' (
  147. id TINYINT(4) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
  148. category VARCHAR(25) NOT NULL,
  149. bgcolor CHAR(6) NOT NULL,
  150. fgcolor CHAR(6) NOT NULL
  151. ) CHARSET=utf8;
  152. ## DEFAULT CATEGORIES
  153. INSERT INTO ' . $wpdb->prefix . AEC_CATEGORY_TABLE . ' (id, category, bgcolor, fgcolor)
  154. VALUES (NULL, "Event", "517ed6", "FFFFFF"),
  155. (NULL, "Deadline", "e3686c", "FFFFFF"),
  156. (NULL, "Volunteer", "8fc9b0", "FFFFFF");';
  157. dbDelta($sql);
  158. }
  159. // add new role
  160. add_role('calendar_contributor', 'Calendar Contributor', array(
  161. 'read' => 1,
  162. 'aec_add_events' => 1
  163. ));
  164. // add calendar capabilities to administrator
  165. $role = get_role('administrator');
  166. $role->add_cap('aec_add_events');
  167. $role->add_cap('aec_manage_events');
  168. $role->add_cap('aec_manage_calendar');
  169. }
  170. function version_patches() {
  171. $plugin_updated = false;
  172. $options = get_option('aec_options');
  173. $current = get_option('aec_version');
  174. // initial and manual option initialization
  175. if (!is_array($options) || !isset($options['reset']) || $options['reset'] == '1') {
  176. update_option('aec_options', $this->plugin_defaults);
  177. }
  178. if (version_compare($current, AEC_VERSION, '==')) {
  179. return;
  180. }
  181. // set version for new plugin installations
  182. if ($current === false) {
  183. update_option('aec_version', AEC_VERSION);
  184. $current = get_option('aec_version');
  185. $plugin_updated = true;
  186. }
  187. // < 0.9.6
  188. if (version_compare($current, '0.9.6', '<')) {
  189. // set title as a required field
  190. $options = $this->insert_option('title', 2);
  191. // update database fields in event table
  192. require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
  193. global $wpdb;
  194. $sql = 'ALTER TABLE ' . $wpdb->prefix . AEC_EVENT_TABLE . ' '
  195. . 'modify venue VARCHAR(100),'
  196. . 'modify city VARCHAR(50),'
  197. . 'modify state CHAR(2),'
  198. . 'modify zip VARCHAR(10),'
  199. . 'modify contact VARCHAR(50),'
  200. . 'modify contact_info VARCHAR(50);';
  201. $wpdb->query($sql);
  202. $plugin_updated = true;
  203. }
  204. // < 0.9.8.1
  205. if (version_compare($current, '0.9.8.1', '<')) {
  206. // add calendar weekend toggle, and event detail map link toggle
  207. $options = $this->insert_option('show_weekends', 1);
  208. $options = $this->insert_option('show_map_link', 1);
  209. $plugin_updated = true;
  210. }
  211. // < 0.9.8.5
  212. if (version_compare($current, '0.9.8.5', '<')) {
  213. // update tables to UTF8 and modify category table
  214. require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
  215. global $wpdb;
  216. $sqla = 'ALTER TABLE ' . $wpdb->prefix . AEC_EVENT_TABLE . ' CONVERT TO CHARACTER SET utf8;';
  217. $wpdb->query($sqla);
  218. $sqlb = 'ALTER TABLE ' . $wpdb->prefix . AEC_CATEGORY_TABLE . ' CONVERT TO CHARACTER SET utf8;';
  219. $wpdb->query($sqlb);
  220. $sqlc = 'ALTER TABLE ' . $wpdb->prefix . AEC_CATEGORY_TABLE . ' '
  221. . 'modify category VARCHAR(100) NOT NULL;';
  222. $wpdb->query($sqlc);
  223. // remove sidebar option
  224. $this->decommission_options(array('sidebar'));
  225. // remove retired administrator capability
  226. $role = get_role('administrator');
  227. $role->remove_cap('aec_run_reports');
  228. // remove retired role
  229. remove_role('blog_calendar_contributor');
  230. // remove outdated widget option
  231. delete_option('widget_upcoming_events');
  232. delete_option('widget_contributor_list');
  233. $plugin_updated = true;
  234. }
  235. // < 0.9.9.1
  236. if (version_compare($current, '0.9.9.1', '<')) {
  237. // update table to support Aussi state length
  238. require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
  239. global $wpdb;
  240. $sql = 'ALTER TABLE ' . $wpdb->prefix . AEC_EVENT_TABLE
  241. . ' MODIFY state CHAR(3);';
  242. $wpdb->query($sql);
  243. // add filter label, description link options and address format options
  244. $options = $this->insert_option('filter_label', 'Show Type');
  245. $options = $this->insert_option('make_links', 0);
  246. $options = $this->insert_option('popup_links', 1);
  247. $options = $this->insert_option('addy_format', 0);
  248. $plugin_updated = true;
  249. }
  250. // < 1.0
  251. if (version_compare($current, '1.0', '<')) {
  252. // update table with repeating event fields, country, larger description, and larger state/province
  253. require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
  254. global $wpdb;
  255. $sql = 'ALTER TABLE ' . $wpdb->prefix . AEC_EVENT_TABLE
  256. . ' MODIFY description VARCHAR(2500),'
  257. . ' MODIFY state VARCHAR(50),'
  258. . ' ADD country VARCHAR(50),'
  259. . ' ADD repeat_freq TINYINT(4) UNSIGNED DEFAULT 0,'
  260. . ' ADD repeat_int TINYINT(4) UNSIGNED DEFAULT 0,'
  261. . ' ADD repeat_end DATE;';
  262. $wpdb->query($sql);
  263. // add mousescroll control, country field, and step d options
  264. $options = $this->insert_option('scroll', 1);
  265. $options = $this->insert_option('country', 0);
  266. $options = $this->insert_option('step_interval', 30);
  267. $plugin_updated = true;
  268. }
  269. // < 1.0.1
  270. if (version_compare($current, '1.0.1', '<')) {
  271. // update to accomodate long urls
  272. require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
  273. global $wpdb;
  274. $sql = 'ALTER TABLE ' . $wpdb->prefix . AEC_EVENT_TABLE
  275. . ' MODIFY link VARCHAR(2000);';
  276. $wpdb->query($sql);
  277. $plugin_updated = true;
  278. }
  279. // update routines completed
  280. if ($plugin_updated) {
  281. // update plugin version
  282. update_option('aec_version', AEC_VERSION);
  283. // add sample event
  284. $_POST['event']['user_id'] = 0; // system id
  285. $_POST['event']['title'] = "Ajax Event Calendar [v" . AEC_VERSION . "] successfully installed!";
  286. $_POST['event']['start_date'] = date('Y-m-d');
  287. $_POST['event']['start_time'] = '00:00:00';
  288. $_POST['event']['end_date'] = date('Y-m-d');
  289. $_POST['event']['end_time'] = '00:00:00';
  290. $_POST['event']['allDay'] = 1;
  291. $_POST['event']['repeat_freq'] = 0;
  292. $_POST['event']['repeat_int'] = 0;
  293. $_POST['event']['repeat_end'] = null;
  294. $_POST['event']['category_id'] = 1;
  295. $_POST['event']['description'] = "Ajax Event Calendar WordPress Plugin is a fully localized (including RTL language support) community calendar that allows authorized users to add, edit, copy, move, resize and delete events into custom categories. Highly customized calendars can be added to pages, posts or text widgets using the <strong>[calendar]</strong> shortcode. Similarly, a list view of events can be added using the <strong>[eventlist]</strong> shortcode. Click on the event link to learn about available the shortcode options.";
  296. $_POST['event']['link'] = AEC_HOMEPAGE;
  297. $_POST['event']['venue'] = 'Cloud Gate "The Bean"';
  298. $_POST['event']['address'] = '201 East Randolph Street';
  299. $_POST['event']['city'] = 'Chicago';
  300. $_POST['event']['state'] = 'Illinois';
  301. $_POST['event']['zip'] = '60601-6530';
  302. $_POST['event']['country'] = 'United States';
  303. $_POST['event']['contact'] = 'Eran Miller';
  304. $_POST['event']['contact_info'] = '123-123-1234';
  305. $_POST['event']['access'] = 1;
  306. $_POST['event']['rsvp'] = 0;
  307. // removes previously created release events and creates a new one
  308. $_POST['user_id'] = $_POST['event']['user_id'];
  309. $this->delete_events_by_user();
  310. $this->db_insert_event($this->cleanse_event_input($_POST['event']), false);
  311. }
  312. }
  313. function set_admin_alert($message) {
  314. array_push($this->admin_messages, print_r($message, true));
  315. }
  316. // display admin alerts
  317. function admin_alert() {
  318. $alerts = $this->admin_messages;
  319. if (count($alerts)) {
  320. foreach ($alerts as $alert) {
  321. printf('<div class="updated">%s</div>', $alert);
  322. }
  323. }
  324. }
  325. function localize_plugin($page) {
  326. load_plugin_textdomain(AEC_NAME, false, AEC_NAME . '/locale/');
  327. $timezone = get_option('timezone_string');
  328. if ($timezone) {
  329. date_default_timezone_set($timezone);
  330. } else {
  331. // TODO: look into converting gmt_offset into timezone_string
  332. date_default_timezone_set('UTC');
  333. }
  334. // localization: date/time
  335. if (get_option('timezone_string')) {
  336. $this->timezone = get_option('timezone_string');
  337. } else {
  338. $this->set_admin_alert(sprintf('<p>Ajax Event Calendar %s.<br>%s... <a href="http://www.travelmath.com/time-zone/" target="_blank"><strong>%s</strong></a>.</p>
  339. <h3><a href="' . admin_url() . 'options-general.php">%s</a></h3>'
  340. , __('requires a city value for the Timezone setting', AEC_NAME)
  341. , __("Not all cities are listed. Can't find your city in the timezone dropdown?", AEC_NAME)
  342. , __('Search for your standardized timezone.', AEC_NAME)
  343. , __('Update Blog Settings', AEC_NAME)));
  344. }
  345. // get_magic_quotes_gpc issue
  346. if (get_magic_quotes_gpc()) {
  347. $this->set_admin_alert(sprintf('<p>%s %s <br>%s <a href="http://wordpress.org/support/topic/plugin-ajax-event-calendar-ajax-event-calendar-dont-like-the-apostrophes?replies=11#post-2259386" target="_blank"> <strong>%s</strong></a>. %s</p>'
  348. , __('Your server has PHP magic_quotes_gpc set to active.', AEC_NAME)
  349. , __('This produces formatting errors in the Ajax Event Calendar plugin.', AEC_NAME)
  350. , __('Learn how to disable this setting', AEC_NAME)
  351. , __('in this forum thread', AEC_NAME)
  352. , __('Ask your host provider for help.', AEC_NAME)));
  353. }
  354. // register scripts
  355. wp_register_script('fullcalendar', AEC_URL . 'js/jquery.fullcalendar.min.js', array('jquery'), '1.5.3', true);
  356. wp_register_script('simplemodal', AEC_URL . 'js/jquery.simplemodal.1.4.3.min.js', array('jquery'), '1.4.3', true);
  357. wp_register_script('jquery-ui-datepicker', AEC_URL . 'js/jquery.ui.datepicker.min.js', array('jquery-ui-core'), '1.8.5', true);
  358. wp_register_script('datepicker-locale', AEC_URL . 'js/i18n/jquery.ui.datepicker-' . substr(get_locale(), 0, 2) . '.js', array('jquery-ui-datepicker'), '1.8.5', true);
  359. wp_register_script('timepicker', AEC_URL . 'js/jquery.timePicker.min.js', array('jquery'), '5195', true);
  360. wp_register_script('growl', AEC_URL . 'js/jquery.jgrowl.min.js', array('jquery'), '1.2.5', true);
  361. wp_register_script('miniColors', AEC_URL . 'js/jquery.miniColors.min.js', array('jquery'), '0.1', true);
  362. wp_register_script('jeditable', AEC_URL . 'js/jquery.jeditable.min.js', array('jquery'), '1.7.1', true);
  363. wp_register_script('mousewheel', AEC_URL . 'js/jquery.mousewheel.min.js', array('jquery'), '3.0.6', true);
  364. wp_register_script('init_admin_calendar', AEC_URL . 'js/jquery.init_admin_calendar.js', array('jquery'), AEC_VERSION, true);
  365. wp_register_script('init_show_calendar', AEC_URL . 'js/jquery.init_show_calendar.js', array('jquery'), AEC_VERSION, true);
  366. wp_register_script('init_show_category', AEC_URL . '/js/jquery.init_admin_category.js', array('jquery'), AEC_VERSION, true);
  367. wp_register_script('tweet', 'http://platform.twitter.com/widgets.js', false, '1.0', true);
  368. wp_register_script('facebook', 'http://connect.facebook.net/en_US/all.js#xfbml=1', false, '1.0', true);
  369. // register styles
  370. wp_register_style('custom', AEC_URL . 'css/custom.css', null, AEC_VERSION);
  371. wp_register_style('custom_rtl', AEC_URL . 'css/custom_rtl.css', null, AEC_VERSION);
  372. wp_register_style('jq_ui_css', AEC_URL . 'css/jquery-ui-1.8.16.custom.css', null, '1.8.16');
  373. }
  374. function render_admin_menu() {
  375. if (function_exists('add_options_page')) {
  376. // main menu page: calendar
  377. $page = add_menu_page('Ajax Event Calendar', __('Calendar', AEC_NAME), 'aec_add_events', AEC_FILE, array($this, 'render_admin_calendar'), AEC_URL . 'css/images/em-icon-16.png', AEC_MENU_POSITION);
  378. // calendar admin specific scripts and styles
  379. add_action("admin_print_scripts-$page", array($this, 'admin_calendar_scripts'));
  380. add_action("admin_print_styles-$page", array($this, 'calendar_styles'));
  381. if (current_user_can('aec_manage_calendar')) {
  382. // sub menu page: category management
  383. $sub_category = add_submenu_page(AEC_FILE, 'Categories', __('Categories', AEC_NAME), 'aec_manage_calendar', 'aec_manage_categories', array($this, 'render_admin_category'));
  384. // category admin specific scripts and styles
  385. add_action("admin_print_scripts-$sub_category", array($this, 'admin_category_scripts'));
  386. add_action("admin_print_scripts-$sub_category", array($this, 'admin_social_scripts'));
  387. add_action("admin_print_styles-$sub_category", array($this, 'admin_category_styles'));
  388. // sub menu page: activity report
  389. $sub_report = add_submenu_page(AEC_FILE, 'Activity Report', __('Activity Report', AEC_NAME), 'aec_manage_calendar', 'aec_activity_report', array($this, 'render_activity_report'));
  390. add_action("admin_print_scripts-$sub_report", array($this, 'admin_social_scripts'));
  391. add_action("admin_print_styles-$sub_report", array($this, 'calendar_styles'));
  392. // sub menu page: calendar options
  393. $sub_options = add_submenu_page(AEC_FILE, 'Options', __('Options', AEC_NAME), 'aec_manage_calendar', 'aec_calendar_options', array($this, 'render_calendar_options'));
  394. add_action("admin_print_scripts-$sub_options", array($this, 'admin_social_scripts'));
  395. add_action("admin_print_styles-$sub_options", array($this, 'calendar_styles'));
  396. }
  397. }
  398. }
  399. // STYLES, SCRIPTS & VIEWS
  400. function localized_variables() {
  401. $options = get_option('aec_options');
  402. // initialize required form fields
  403. foreach ($options as $option => $value) {
  404. if ($value == 2) {
  405. $this->add_required_field($option);
  406. }
  407. }
  408. $isEuroDate = $this->parse_date_format(AEC_WP_DATE_FORMAT);
  409. $is24HrTime = $this->parse_time_format(AEC_WP_TIME_FORMAT);
  410. return array(
  411. 'is_rtl' => is_rtl(),
  412. 'locale' => AEC_LOCALE,
  413. 'start_of_week' => get_option('start_of_week'),
  414. 'step_interval' => intval($options['step_interval'], 10),
  415. 'datepicker_format' => ($isEuroDate) ? 'dd-mm-yy' : 'mm/dd/yy', // jquery datepicker format
  416. 'is24HrTime' => $is24HrTime,
  417. 'show_weekends' => $options['show_weekends'],
  418. 'agenda_time_format' => ($is24HrTime) ? 'H:mm{ - H:mm}' : 'h:mmt{ - h:mmt}',
  419. 'other_time_format' => ($is24HrTime) ? 'H:mm' : 'h:mmt',
  420. 'axis_time_format' => ($is24HrTime) ? 'HH:mm' : 'h:mmt',
  421. 'limit' => $options['limit'],
  422. 'today' => __('Today', AEC_NAME),
  423. 'all_day' => __('All Day', AEC_NAME),
  424. 'years' => __('Years', AEC_NAME),
  425. 'year' => __('Year', AEC_NAME),
  426. 'months' => __('Months', AEC_NAME),
  427. 'month' => __('Month', AEC_NAME),
  428. 'weeks' => __('Weeks', AEC_NAME),
  429. 'week' => __('Week', AEC_NAME),
  430. 'days' => __('Days', AEC_NAME),
  431. 'day' => __('Day', AEC_NAME),
  432. 'hours' => __('Hours', AEC_NAME),
  433. 'hour' => __('Hour', AEC_NAME),
  434. 'minutes' => __('Minutes', AEC_NAME),
  435. 'minute' => __('Minute', AEC_NAME),
  436. 'january' => __('January', AEC_NAME),
  437. 'february' => __('February', AEC_NAME),
  438. 'march' => __('March', AEC_NAME),
  439. 'april' => __('April', AEC_NAME),
  440. 'may' => __('May', AEC_NAME),
  441. 'june' => __('June', AEC_NAME),
  442. 'july' => __('July', AEC_NAME),
  443. 'august' => __('August', AEC_NAME),
  444. 'september' => __('September', AEC_NAME),
  445. 'october' => __('October', AEC_NAME),
  446. 'november' => __('November', AEC_NAME),
  447. 'december' => __('December', AEC_NAME),
  448. 'jan' => __('Jan', AEC_NAME),
  449. 'feb' => __('Feb', AEC_NAME),
  450. 'mar' => __('Mar', AEC_NAME),
  451. 'apr' => __('Apr', AEC_NAME),
  452. 'may_short' => _x('May', 'Three-letter month name abbreviation', AEC_NAME),
  453. 'jun' => __('Jun', AEC_NAME),
  454. 'jul' => __('Jul', AEC_NAME),
  455. 'aug' => __('Aug', AEC_NAME),
  456. 'sep' => __('Sep', AEC_NAME),
  457. 'oct' => __('Oct', AEC_NAME),
  458. 'nov' => __('Nov', AEC_NAME),
  459. 'dec' => __('Dec', AEC_NAME),
  460. 'sunday' => __('Sunday', AEC_NAME),
  461. 'monday' => __('Monday', AEC_NAME),
  462. 'tuesday' => __('Tuesday', AEC_NAME),
  463. 'wednesday' => __('Wednesday', AEC_NAME),
  464. 'thursday' => __('Thursday', AEC_NAME),
  465. 'friday' => __('Friday', AEC_NAME),
  466. 'saturday' => __('Saturday', AEC_NAME),
  467. 'sun' => __('Sun', AEC_NAME),
  468. 'mon' => __('Mon', AEC_NAME),
  469. 'tue' => __('Tue', AEC_NAME),
  470. 'wed' => __('Wed', AEC_NAME),
  471. 'thu' => __('Thu', AEC_NAME),
  472. 'fri' => __('Fri', AEC_NAME),
  473. 'sat' => __('Sat', AEC_NAME),
  474. 'close_event_form' => __('Close Event Form', AEC_NAME),
  475. 'loading_event_form' => __('Loading Event Form...', AEC_NAME),
  476. 'update_btn' => __('Update', AEC_NAME),
  477. 'delete_btn' => __('Delete', AEC_NAME),
  478. 'category_type' => __('Category type', AEC_NAME),
  479. 'hide_all_notifications' => __('hide all notifications', AEC_NAME),
  480. 'has_been_created' => __('has been created.', AEC_NAME),
  481. 'has_been_modified' => __('has been modified.', AEC_NAME),
  482. 'has_been_deleted' => __('has been deleted.', AEC_NAME),
  483. 'add_event' => __('Add Event', AEC_NAME),
  484. 'edit_event' => __('Edit Event', AEC_NAME),
  485. 'delete_event' => __('Delete this event?', AEC_NAME),
  486. 'loading' => __('Loading Events...', AEC_NAME),
  487. 'category_filter_label' => __('Category filter label', AEC_NAME),
  488. 'repeats_every' => __('Repeats Every', AEC_NAME),
  489. 'until' => __('Until', AEC_NAME),
  490. 'success' => __('Success!', AEC_NAME),
  491. 'whoops' => __('Whoops!', AEC_NAME)
  492. );
  493. }
  494. function admin_calendar_variables() {
  495. $is_admin = (current_user_can('aec_manage_events')) ? 1 : 0;
  496. $options = get_option('aec_options');
  497. return array_merge($this->localized_variables(),
  498. array(
  499. 'admin' => $is_admin,
  500. 'scroll' => $options['scroll'],
  501. 'required_fields' => join(",", $this->get_required_fields()),
  502. 'editable' => true,
  503. 'error_no_rights' => __('You cannot edit events created by other users.', AEC_NAME),
  504. 'error_past_create' => __('You cannot create events in the past.', AEC_NAME),
  505. 'error_future_create' => __('You cannot create events more than a year in advance.', AEC_NAME),
  506. 'error_past_resize' => __('You cannot resize expired events.', AEC_NAME),
  507. 'error_past_move' => __('You cannot move events into the past.', AEC_NAME),
  508. 'error_past_edit' => __('You cannot edit expired events.', AEC_NAME),
  509. 'error_invalid_duration' => __('Invalid duration.', AEC_NAME)
  510. )
  511. );
  512. }
  513. function frontend_calendar_variables() {
  514. return array_merge($this->localized_variables(),
  515. array(
  516. 'ajaxurl' => admin_url('admin-ajax.php', is_ssl() ? 'https' : 'http'),
  517. 'editable' => false
  518. )
  519. );
  520. }
  521. function admin_category_variables() {
  522. return array_merge($this->localized_variables(),
  523. array(
  524. 'error_blank_category' => __('Category type cannot be a blank value.', AEC_NAME),
  525. 'confirm_category_delete' => __('Are you sure you want to delete this category type?', AEC_NAME),
  526. 'confirm_category_reassign' => __('Several events are associated with this category. Click OK to reassign these events to the default category.', AEC_NAME),
  527. 'events_reassigned' => __('Events have been reassigned to the default category.', AEC_NAME)
  528. )
  529. );
  530. }
  531. function calendar_styles() {
  532. // disabled: until I can conditionally load these scripts in text widgets with shortcodes
  533. // if ($this->has_shortcode('calendar') || $this->has_shortcode('eventlist')) {
  534. wp_enqueue_style('jq_ui_css');
  535. wp_enqueue_style('categories');
  536. wp_enqueue_style('custom');
  537. if (is_rtl()) {
  538. wp_enqueue_style('custom_rtl');
  539. }
  540. //}
  541. }
  542. function admin_category_styles() {
  543. wp_enqueue_style('categories');
  544. wp_enqueue_style('custom');
  545. if (is_rtl()) {
  546. wp_enqueue_style('custom_rtl');
  547. }
  548. }
  549. function admin_calendar_scripts() {
  550. wp_enqueue_script('jquery');
  551. wp_enqueue_script('jquery-ui-core');
  552. wp_enqueue_script('jquery-ui-draggable');
  553. wp_enqueue_script('jquery-ui-resizable');
  554. wp_enqueue_script('jquery-ui-datepicker');
  555. if (AEC_LOCALE != 'en') {
  556. wp_enqueue_script('datepicker-locale'); // if not in English, load localization
  557. }
  558. wp_enqueue_script('fullcalendar');
  559. wp_enqueue_script('simplemodal');
  560. wp_enqueue_script('growl');
  561. wp_enqueue_script('timepicker');
  562. wp_enqueue_script('mousewheel');
  563. wp_enqueue_script('init_admin_calendar');
  564. wp_localize_script('init_admin_calendar', 'custom', $this->admin_calendar_variables());
  565. }
  566. function frontend_calendar_scripts() {
  567. if (is_admin()) {
  568. return;
  569. }
  570. wp_enqueue_script('jquery');
  571. wp_enqueue_script('fullcalendar');
  572. wp_enqueue_script('simplemodal');
  573. wp_enqueue_script('mousewheel');
  574. wp_enqueue_script('growl');
  575. wp_enqueue_script('jquery-ui-datepicker');
  576. if (AEC_LOCALE != 'en') {
  577. wp_enqueue_script('datepicker-locale'); // if not in English, load localization
  578. }
  579. wp_enqueue_script('init_show_calendar');
  580. wp_localize_script('init_show_calendar', 'custom', $this->frontend_calendar_variables());
  581. }
  582. function admin_social_scripts() {
  583. wp_enqueue_script('tweet');
  584. wp_enqueue_script('facebook');
  585. }
  586. function admin_category_scripts() {
  587. wp_enqueue_script('jquery');
  588. wp_enqueue_script('growl');
  589. wp_enqueue_script('miniColors');
  590. wp_enqueue_script('jeditable');
  591. wp_enqueue_script('init_show_category');
  592. wp_localize_script('init_show_category', 'custom', $this->admin_category_variables());
  593. }
  594. function render_aec_version() {
  595. return "<span class='aec-credit'>AEC v" . AEC_VERSION . "</span>\n";
  596. }
  597. function render_admin_calendar() {
  598. if (!current_user_can('aec_add_events')) {
  599. wp_die(__('You do not have sufficient permissions to access this page.', AEC_NAME));
  600. }
  601. $options = get_option('aec_options');
  602. $out = $this->generate_css();
  603. $out .= "<div class='wrap'>\n";
  604. $out .= "<a href='". AEC_HOMEPAGE . "' target='_blank'><span class='em-icon icon32'></span></a>\n";
  605. $out .= $this->render_category_filter($options);
  606. $out .= "<h2>" . __('Ajax Event Calendar', AEC_NAME) . "</h2>\n";
  607. $out .= "<div id='aec-calendar'></div>\n";
  608. $out .= $this->render_aec_version();
  609. $out .= "</div>\n";
  610. echo $out;
  611. }
  612. function render_shortcode_calendar($atts) {
  613. extract(shortcode_atts(array(
  614. 'categories' => '',
  615. 'excluded' => 0,
  616. 'filter' => 'all',
  617. 'month' => date('m'),
  618. 'year' => date('Y'),
  619. 'view' => 'month',
  620. 'views' => 'month,agendaWeek',
  621. 'nav' => 'prev,next, today',
  622. 'height' => '',
  623. 'scroll' => 0,
  624. 'mini' => 0
  625. ), $atts));
  626. // shortcode input validation
  627. $isTrue = array("true", "1");
  628. $isFalse = array("false", "0");
  629. $viewopts = array("month", "agendaWeek", "agendaDay", "basicWeek", "basicDay");
  630. $categories = $this->cleanse_shortcode_input($categories);
  631. $excluded = ($categories && $excluded) ? $excluded : 0;
  632. if (in_array($filter, $isFalse, true)) {
  633. $filter = false;
  634. } elseif (intval($filter)) {
  635. $filter = 'cat' . intval($filter);
  636. } else {
  637. $filter = 'all';
  638. }
  639. $month = intval($month)-1;
  640. if ($year != date('Y')) {
  641. $year = intval($year);
  642. }
  643. if (!in_array($view, $viewopts)) {
  644. $view = 'month';
  645. }
  646. if (!intval($height)) {
  647. $height = '';
  648. }
  649. if (in_array($scroll, $isTrue, true)) {
  650. $scroll = 1;
  651. }
  652. if (in_array($mini, $isTrue, true)) {
  653. $mini = 1;
  654. $views = '';
  655. $filter = 0;
  656. $height = 200;
  657. }
  658. $out = $this->generate_css();
  659. // pass shortcode parameters to javascript
  660. $out .= "<script type='text/javascript'>\n";
  661. $out .= "var shortcode = {\n";
  662. $out .= "categories: '{$categories}',\n";
  663. $out .= "excluded: {$excluded},\n";
  664. $out .= "filter: '{$filter}',\n";
  665. $out .= "view: '{$view}',\n";
  666. $out .= "month: {$month},\n";
  667. $out .= "year: {$year},\n";
  668. $out .= "views: '{$views}',\n";
  669. $out .= "nav: '{$nav}',\n";
  670. $out .= "height: '{$height}',\n";
  671. $out .= "scroll: {$scroll},\n";
  672. $out .= "mini: {$mini}\n";
  673. $out .= "};\n";
  674. $out .= "</script>\n";
  675. $out .= "<div id='aec-container'>\n";
  676. $out .= "<div id='aec-header'>\n";
  677. $options = get_option('aec_options');
  678. if ($options['menu']) {
  679. $out .= "<div id='aec-menu'>\n";
  680. $out .= "<a href='" . admin_url() . "admin.php?page=ajax-event-calendar.php'>" . __('Add Events', AEC_NAME) . "</a>";
  681. $out .= "</div>\n";
  682. }
  683. if ($filter) {
  684. $out .= $this->render_category_filter($options, $categories, $excluded);
  685. }
  686. $out .= "</div>\n";
  687. $out .= "<div id='aec-calendar'></div>\n";
  688. $out .= $this->render_aec_version();
  689. $out .= "</div>\n";
  690. return $out;
  691. }
  692. function render_shortcode_eventlist($atts) {
  693. // shortcode defaults
  694. extract(shortcode_atts(array(
  695. 'categories' => false,
  696. 'excluded' => false,
  697. 'start' => date('Y-m-d'),
  698. 'end' => date('Y-m-d', mktime(0, 0, 0, date("m"), date("d"), date("Y")+1)),
  699. 'limit' => 4,
  700. 'whitelabel' => false,
  701. 'noresults' => __('No upcoming events', AEC_NAME)
  702. ), $atts));
  703. // shortcode input validation
  704. $categories = (isset($categories)) ? $this->cleanse_shortcode_input($categories) : false;
  705. $excluded = ($categories && isset($excluded)) ? $excluded : false;
  706. $limit = ($limit == "none") ? false : intval($limit);
  707. $whitelabel = ($whitelabel == "true") ? true : false;
  708. $start = date('Y-m-d', strtotime($start));
  709. $end = date('Y-m-d', strtotime($end));
  710. $events = $this->db_query_events($start, $end, $categories, $excluded, $limit);
  711. $events = $this->process_events($events, $start, $end, true);
  712. $out = $this->generate_css();
  713. $out .= "<ul class='aec-eventlist'>";
  714. if ($events) {
  715. $out .= $this->render_eventlist_events($events, $whitelabel, $limit);
  716. } else {
  717. $out .= "<li>{$noresults}</li>";
  718. }
  719. $out .= "</ul>\n";
  720. $out .= $this->render_aec_version();
  721. return $out;
  722. }
  723. function render_calendar_events() {
  724. $categories = (isset($_POST['categories'])) ? $this->cleanse_shortcode_input($_POST['categories']) : false;
  725. $excluded = ($categories && isset($_POST['excluded'])) ? $_POST['excluded'] : false;
  726. $start = date('Y-m-d', $_POST['start']);
  727. $end = date('Y-m-d', $_POST['end']);
  728. $readonly = (isset($_POST['readonly'])) ? true : false;
  729. $events = $this->db_query_events($start, $end, $categories, $excluded);
  730. $this->render_json($this->process_events($events, $start, $end, $readonly));
  731. }
  732. function render_eventlist_events($events, $whitelabel, $limit) {
  733. usort($events, array($this, 'array_compare_order'));
  734. $rows = $this->convert_array_to_object($events);
  735. $out = '';
  736. foreach ($rows as $count => $row) {
  737. //if ($count < $limit) {
  738. if (!$limit || $count < $limit) {
  739. // split database formatted datetime value into display formatted date and time values
  740. $row->start_date = $this->convert_date($row->start, AEC_DB_DATETIME_FORMAT, AEC_WP_DATE_FORMAT);
  741. $row->start_time = $this->convert_date($row->start, AEC_DB_DATETIME_FORMAT, AEC_WP_TIME_FORMAT);
  742. $row->end_date = $this->convert_date($row->end, AEC_DB_DATETIME_FORMAT, AEC_WP_DATE_FORMAT);
  743. $row->end_time = $this->convert_date($row->end, AEC_DB_DATETIME_FORMAT, AEC_WP_TIME_FORMAT);
  744. // link to event
  745. $class = ($whitelabel) ? '' : ' ' . $row->className;
  746. $out .= '<li class="fc-event round5' . $class . '" onClick="jQuery.aecDialog({\'id\':' . $row->id . ',\'start\':\'' . $row->start . '\',\'end\':\'' . $row->end . '\'});">';
  747. $out .= '<span class="fc-event-time">';
  748. $out .= $row->start_date;
  749. if (!$row->allDay) {
  750. $out .= ' ' . $row->start_time;
  751. }
  752. $out .= '</span>';
  753. $out .= '<span class="fc-event-title">' . $this->render_i18n_data($row->title) . '</span>';
  754. $out .= '</li>';
  755. }
  756. }
  757. return $out;
  758. }
  759. function render_category_filter($options, $categories=false, $excluded=false) {
  760. $categories = $this->db_query_categories($categories, $excluded);
  761. if (sizeof($categories) > 1) {
  762. $out = "<ul id='aec-filter'>\n";
  763. $out .= "<li>" . $this->render_i18n_data($options['filter_label']) . "</li>\n";
  764. $out .= '<li class="active"><a class="round5 all">' . __('All', AEC_NAME) . '</a></li>' . "\n";
  765. foreach ($categories as $category) {
  766. $out .= '<li><a class="round5 cat' . $category->id . '">' . $this->render_i18n_data($category->category) . '</a></li>' . "\n";
  767. }
  768. $out .= "</ul>\n";
  769. return $out;
  770. }
  771. }
  772. function render_admin_modal() {
  773. if (!current_user_can('aec_add_events')) {
  774. wp_die(__('You do not have sufficient permissions to access this page.', AEC_NAME));
  775. }
  776. require_once AEC_PATH . 'inc/admin-event.php';
  777. exit();
  778. }
  779. function render_frontend_modal() {
  780. require_once AEC_PATH . 'inc/show-event.php';
  781. }
  782. function render_admin_category() {
  783. if (!current_user_can('aec_manage_calendar')) {
  784. wp_die(__('You do not have sufficient permissions to access this page.', AEC_NAME));
  785. }
  786. $add = $this->generate_css();
  787. $add .= $this->add_wrap(__('To add a new category, enter a category label and select a background color.', AEC_NAME), "<p>", "</p>");
  788. $add .= "<form id='aec-category-form'>\n";
  789. $add .= "<input type='hidden' id='fgcolor' name='fgcolor' class='fg ltr' value='#FFFFFF' />";
  790. $add .= "<p><input type='text' id='category' name='category' value='' /> ";
  791. $add .= "<input class='bg colors ltr' type='text' id='bgcolor' name='bgcolor' value='#005294' size='7' maxlength='7' autocomplete='off' /> ";
  792. $add .= $this->add_wrap(__('Add', AEC_NAME), "<button class='add button-primary'>", "</button></p>");
  793. $add .= "</form>\n";
  794. $aec_options = get_option('aec_options');
  795. $add .= $this->add_wrap(__('Category filter label', AEC_NAME), "<p>", "</p>");
  796. $add .= $this->add_wrap("<input type='text' name='filter_label' id='filter_label' value='" . esc_attr($this->render_i18n_data($aec_options['filter_label'])) . "' />", "<p>", "");
  797. $add .= $this->add_wrap(__('Update', AEC_NAME), "<button id='filter_update' class='filter-update button-secondary'>", "</button></p>");
  798. $add .= $this->add_wrap(__('Category IDs are displayed in color bubbles at the beginning of each row.' , AEC_NAME), "<p>", "<br/>");
  799. $add .= $this->add_wrap(__('To change category color, click the color swatch or edit the hex color value and click Update.', AEC_NAME), "", "</p>");
  800. $add .= "<form id='aec-category-list'>\n";
  801. $categories = $this->db_query_categories();
  802. foreach ($categories as $category) {
  803. $add .= "<p id='id_{$category->id}'>\n";
  804. $add .= "<input type='hidden' name='fgcolor' value='#{$category->fgcolor}' class='fg ltr' />\n";
  805. $add .= "<span class='round5 cat{$category->id}'>{$category->id}</span> ";
  806. $add .= "<input type='text' name='category' value='" . $this->render_i18n_data($category->category) . "' class='edit' />\n";
  807. $add .= "<input type='text' name='bgcolor' size='7' maxlength='7' autocomplete='off' value='#{$category->bgcolor}' class='bg colors ltr' />\n";
  808. $add .= $this->add_wrap(__('Update', AEC_NAME), "<button class='update button-secondary'>", "</button>");
  809. if ($category->id > 1) {
  810. $add .= $this->add_wrap(__('Delete', AEC_NAME), "<button class='button-secondary delete'>", "</button>");
  811. }
  812. $add .= "</p>\n";
  813. }
  814. $add .= "</form>\n";
  815. $out = $this->add_panel(__('Manage Categories', AEC_NAME), $add);
  816. $top = "<a href='http://". AEC_HOMEPAGE . "' target='_blank'><span class='em-icon icon32'></span></a>\n";
  817. $top .= $this->add_wrap(__('Categories', AEC_NAME), "<h2>", "</h2>");
  818. $out = $this->add_wrap($out, "<div class='postbox-container' style='width:65%'>", "</div>");
  819. $out .= $this->add_sidebar();
  820. echo $this->add_wrap($out, "<div class='wrap'>{$top}", "</div>");
  821. }
  822. function render_activity_report() {
  823. if (!current_user_can('aec_manage_calendar')) {
  824. wp_die(__('You do not have sufficient permissions to access this page.', AEC_NAME));
  825. }
  826. $rows = $this->db_query_monthly_activity();
  827. $out = $this->generate_css();
  828. if (count($rows)) {
  829. foreach ($rows as $row) {
  830. $out .= "<p class='round5 cat{$row->category_id}'>{$row->cnt} ";
  831. $out .= $this->render_i18n_data($row->category);
  832. $out .= " " . _n('Event', 'Events', $row->cnt, AEC_NAME);
  833. $out .= "</p>\n";
  834. }
  835. $out .= $this->add_wrap(__('NOTE: Each repeating event is counted once.', AEC_NAME), "<p><em>", "</em></p>");
  836. } else {
  837. $out .= $this->add_wrap(__('No events this month.', AEC_NAME), "<p><em>", "</em></p>");
  838. }
  839. $out = $this->add_panel(__('Number of events scheduled for the current month, by category:', AEC_NAME), $out);
  840. $top = "<a href='http://". AEC_HOMEPAGE . "' target='_blank'><span class='em-icon icon32'></span></a>\n";
  841. $top .= $this->add_wrap(__('Activity Report', AEC_NAME), "<h2>", "</h2>");
  842. $out = $this->add_wrap($out, "<div class='postbox-container' style='width:65%'>", "</div>");
  843. $out .= $this->add_sidebar();
  844. echo $this->add_wrap($out, "<div class='wrap'>{$top}", "</div>");
  845. }
  846. function render_calendar_options() {
  847. if (!current_user_can('aec_manage_calendar')) {
  848. wp_die(__('You do not have sufficient permissions to access this page.', AEC_NAME));
  849. }
  850. require_once AEC_PATH . 'inc/admin-options.php';
  851. }
  852. function process_events($events, $start, $end, $readonly) {
  853. if ($events) {
  854. $output = array();
  855. foreach ($events as $event) {
  856. $event->view_start = $start;
  857. $event->view_end = $end;
  858. $event = $this->process_event($event, $readonly, true);
  859. if (is_array($event)) {
  860. foreach ($event as $repeat) {
  861. array_push($output, $repeat);
  862. }
  863. } else {
  864. array_push($output, $event);
  865. }
  866. }
  867. return $output;
  868. }
  869. }
  870. function process_event($input, $readonly=false, $queue=false) {
  871. $output = array();
  872. if ($repeats = $this->generate_repeating_event($input)) {
  873. foreach ($repeats as $repeat) {
  874. array_push($output, $this->generate_event($repeat, $this->return_auth($readonly), $queue));
  875. }
  876. } else {
  877. array_push($output, $this->generate_event($input, $this->return_auth($readonly), $queue));
  878. }
  879. if ($queue) {
  880. return $output;
  881. }
  882. $this->render_json($output);
  883. }
  884. function generate_repeating_event($event) {
  885. if ($event->repeat_freq) {
  886. $event_start = strtotime($event->start);
  887. $event_end = strtotime($event->end);
  888. $repeat_end = strtotime($event->repeat_end) + 86400;
  889. $view_start = strtotime($event->view_start);
  890. $view_end = strtotime($event->view_end);
  891. $repeats = array();
  892. while($event_start < $repeat_end) {
  893. if ($event_start >= $view_start && $event_start <= $view_end) {
  894. $event = clone $event; // clone event details and override dates
  895. $event->start = date(AEC_DB_DATETIME_FORMAT, $event_start);
  896. $event->end = date(AEC_DB_DATETIME_FORMAT, $event_end);
  897. array_push($repeats, $event);
  898. }
  899. $event_start = $this->get_next_date($event_start, $event->repeat_freq, $event->repeat_int);
  900. $event_end = $this->get_next_date($event_end, $event->repeat_freq, $event->repeat_int);
  901. }
  902. return $repeats;
  903. }
  904. return false;
  905. }
  906. function get_next_date($date, $freq, $int) {
  907. if ($int == 0) return strtotime("+" . $freq . " days", $date);
  908. if ($int == 1) return strtotime("+" . $freq . " weeks", $date);
  909. if ($int == 2) return $this->get_next_month($date, $freq);
  910. if ($int == 3) return $this->get_next_year($date, $freq);
  911. }
  912. function get_next_month($date, $n = 1) {
  913. $newDate = strtotime("+{$n} months", $date);
  914. // adjustment for events that repeat on the 29th, 30th and 31st of a month
  915. if (date('j', $date) !== (date('j', $newDate))) {
  916. $newDate = strtotime("+" . $n+1 . " months", $date);
  917. }
  918. return $newDate;
  919. }
  920. function get_next_year($date, $n = 1) {
  921. $newDate = strtotime("+{$n} years", $date);
  922. // adjustment for events that repeat on february 29th
  923. if (date('j', $date) !== (date('j', $newDate))) {
  924. $newDate = strtotime("+" . $n+3 . " years", $date);
  925. }
  926. return $newDate;
  927. }
  928. function generate_event($input, $user_id) {
  929. $permissions = new stdClass();
  930. $permissions = $this->get_event_permissions($input, $user_id);
  931. $repeats = ($input->repeat_freq) ? ' aec-repeating' : '';
  932. $output = array(
  933. 'id' => $input->id,
  934. 'title' => $input->title,
  935. 'start' => $input->start,
  936. 'end' => $input->end,
  937. 'allDay' => ($input->allDay) ? true : false,
  938. 'className' => "cat{$input->category_id}{$permissions->cssclass}{$repeats}",
  939. 'editable' => $permissions->editable,
  940. 'repeat_i' => $input->repeat_int,
  941. 'repeat_f' => $input->repeat_freq,
  942. 'repeat_e' => $input->repeat_end
  943. );
  944. return $output;
  945. }
  946. function get_event_permissions($input, $user_id) {
  947. $permissions = new stdClass();
  948. // users that are not logged-in see all events
  949. if ($user_id == -1) {
  950. $permissions->editable = false;
  951. $permissions->cssclass = '';
  952. } else {
  953. // users with aec_manage_events capability can edit all events
  954. // users with aec_add_events capability can edit events only they create
  955. if ($input->user_id == $user_id || $user_id == false) {
  956. $permissions->editable = true;
  957. $permissions->cssclass = '';
  958. } else {
  959. $permissions->editable = false;
  960. $permissions->cssclass = ' fc-event-disabled';
  961. }
  962. }
  963. return $permissions;
  964. }
  965. // OPTION CONTROLS
  966. function add_panel($name, $content) {
  967. $before = "<div class='metabox-holder'>\n";
  968. $before .= "<div class='postbox'>\n";
  969. $before .= "<h3 style='cursor:default'><span>{$name}</span></h3>\n";
  970. $before .= "<div class='inside'>\n";
  971. $after = str_repeat("</div>\n", 3);
  972. return $this->add_wrap($content, $before, $after);
  973. }
  974. function add_hidden_field($field, $value=false) {
  975. if ($value === false) {
  976. $aec_options = get_option('aec_options');
  977. $value = $aec_options[$field];
  978. }
  979. return "<input type='hidden' name='aec_options[{$field}]' value='{$value}' />\n";
  980. }
  981. function add_text_field($field, $label, $tip=false) {
  982. $aec_options = get_option('aec_options');
  983. $out = "<label for='{$field}' class='semi'>{$label}</label>\n";
  984. $out .= "<input type='text' name='aec_options[{$field}]' id='{$field}' value='" . esc_attr($aec_options[$field]) . "' />\n";
  985. if ($tip) {
  986. $out .= "<span class='description'>{$tip}</span>\n";
  987. }
  988. return $this->add_wrap($out, '<p class="hhh">', '</p>');
  989. }
  990. function add_checkbox_field($field, $label, $tip=false) {
  991. $aec_options = get_option('aec_options');
  992. $checked = ($aec_options[$field]) ? ' checked="checked" ' : ' ';
  993. $out = $this->add_hidden_field($field, 0);
  994. $out .= "<input type='checkbox' name='aec_options[{$field}]' id='{$field}' value='1' {$checked} />\n";
  995. $out .= "<label for='{$field}' class='auto'>{$label}</label>\n";
  996. if ($tip) {
  997. $out .= "<span class='description'>{$tip}</span>\n";
  998. }
  999. return $this->add_wrap($out, '<p class="hhh">', '</p>');
  1000. }
  1001. function add_select_field($field, $label, $options, $values=false) {
  1002. $aec_options = get_option('aec_options');
  1003. $out = "<label for='{$field}'>{$label}</label>\n";
  1004. $out .= "<select id='{$field}' class='semi' name='aec_options[{$field}]'>";
  1005. foreach ($options as $option => $value) {
  1006. if (is_numeric($value)) $option = $value;
  1007. if ($values) {
  1008. $option = $values[$option];
  1009. }
  1010. $out .= "<option value='{$option}' name='aec_options[{$field}]' " . selected($aec_options[$field], $option, false) . ">{$value}</option>\n";
  1011. }
  1012. $out .= "</select>\n";
  1013. return $this->add_wrap($out, '<p class="hhh">', '</p>');
  1014. }
  1015. function add_wrap($content, $before='', $after='') {
  1016. return "{$before}{$content}{$after}\n";
  1017. }
  1018. function add_sidebar() {
  1019. $help = $this->add_wrap(__('Read about installation and options', AEC_NAME), "<p><a href='" . AEC_HOMEPAGE . "installation/' target='_blank'>", "</a>.</p>");
  1020. $help .= $this->add_wrap(__('Review the FAQ', AEC_NAME), "<p><a href='" . AEC_HOMEPAGE . "faq/' target='_blank'>", "</a>.</p>");
  1021. $help .= $this->add_wrap(__('Ask for help in the WordPress forum', AEC_NAME), "<p><a href='http://wordpress.org/tags/ajax-event-calendar' target='_blank'>", "</a>.</p>");
  1022. $help .= $this->add_wrap(__('Use the issue tracker', AEC_NAME), "<p><a href='http://code.google.com/p/wp-aec/issues/list' target='_blank'>", "</a> ");
  1023. $help .= $this->add_wrap(__('to track and report bugs, feature requests, and to submit', AEC_NAME), "", "");
  1024. $help .= $this->add_wrap(__('poEdit', AEC_NAME), " (<a href='http://weblogtoolscollection.com/archives/2007/08/27/localizing-a-wordpress-plugin-using-poedit/' target='_blank'>", "</a>)");
  1025. $help .= $this->add_wrap(__('translation files', AEC_NAME), "", ".</p>");
  1026. $like = $this->add_wrap(__('Give the plugin a good rating', AEC_NAME), "<p><a href='" . AEC_HOMEPAGE . "' target='_blank'>", "</a>.</p>");
  1027. $like .= $this->add_wrap(__('Make a donation in recognition of countless hours spent making this plugin', AEC_NAME), "<p>", "</p>");
  1028. $like .= $this->add_wrap("<form style='text-align:center' action='https://www.paypal.com/cgi-bin/webscr' method='post'><input type='hidden' name='cmd' value='_s-xclick' /><input type='hidden' name='hosted_button_id' value='NCDKRE46K2NBA' /><input type='image' src='https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif' name='submit' alt='PayPal - The safer, easier way to pay online!' /><img alt='' border='0' src='https://www.paypalobjects.com/en_US/i/scr/pixel.gif' width='1' height='1' /></form>", "<p>", "</p>");
  1029. $social = $this->add_wrap(__('Create a blog review or an instructional video about the Calendar and share it', AEC_NAME), "<p>", ".</p>");
  1030. $social .= $this->add_wrap("<a href='http://twitter.com/share' class='twitter-share-button' data…

Large files files are truncated, but you can click here to view the full file