PageRenderTime 99ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 1ms

/wp-content/plugins/events-manager/classes/em-events.php

https://gitlab.com/Blueprint-Marketing/interoccupy.net
PHP | 397 lines | 295 code | 31 blank | 71 comment | 85 complexity | 18efc7a56329713604c6fb67beeb1fd9 MD5 | raw file
  1. <?php
  2. //TODO EM_Events is currently static, better we make this non-static so we can loop sets of events, and standardize with other objects.
  3. /**
  4. * Use this class to query and manipulate sets of events. If dealing with more than one event, you probably want to use this class in some way.
  5. *
  6. */
  7. class EM_Events extends EM_Object implements Iterator {
  8. /**
  9. * Array of EM_Event objects
  10. * @var array EM_Event
  11. */
  12. var $events = array();
  13. function EM_Events( $args = array() ){
  14. if( is_array($args) ){
  15. if( is_object(current($args)) && get_class(current($args)) == 'EM_Event' ){
  16. $this->events = $args;
  17. }else{
  18. $this->events = EM_Events::get($args);
  19. }
  20. }else{
  21. $this->events = EM_Events::get();
  22. }
  23. do_action('em_events',$this);
  24. }
  25. /**
  26. * Returns an array of EM_Events that match the given specs in the argument, or returns a list of future evetnts in future
  27. * (see EM_Events::get_default_search() ) for explanation of possible search array values. You can also supply a numeric array
  28. * containing the ids of the events you'd like to obtain
  29. *
  30. * @param array $args
  31. * @return EM_Event array()
  32. */
  33. function get( $args = array(), $count=false ) {
  34. global $wpdb;
  35. $events_table = EM_EVENTS_TABLE;
  36. $locations_table = EM_LOCATIONS_TABLE;
  37. //Quick version, we can accept an array of IDs, which is easy to retrieve
  38. if( self::array_is_numeric($args) ){ //Array of numbers, assume they are event IDs to retreive
  39. //We can just get all the events here and return them
  40. $sql = "
  41. SELECT * FROM $events_table
  42. LEFT JOIN $locations_table ON {$locations_table}.location_id={$events_table}.location_id
  43. WHERE event_id=".implode(" OR event_id=", $args)."
  44. ";
  45. $results = $wpdb->get_results(apply_filters('em_events_get_sql',$sql),ARRAY_A);
  46. $events = array();
  47. foreach($results as $result){
  48. $events[$result['event_id']] = new EM_Event($result);
  49. }
  50. return $events; //We return all the events matched as an EM_Event array.
  51. }
  52. //We assume it's either an empty array or array of search arguments to merge with defaults
  53. $args = self::get_default_search($args);
  54. $limit = ( $args['limit'] && is_numeric($args['limit'])) ? "LIMIT {$args['limit']}" : '';
  55. $offset = ( $limit != "" && is_numeric($args['offset']) ) ? "OFFSET {$args['offset']}" : '';
  56. //Get the default conditions
  57. $conditions = self::build_sql_conditions($args);
  58. //Put it all together
  59. $where = ( count($conditions) > 0 ) ? " WHERE " . implode ( " AND ", $conditions ):'';
  60. //Get ordering instructions
  61. $EM_Event = new EM_Event();
  62. $EM_Location = new EM_Location();
  63. $orderby = self::build_sql_orderby($args, array_keys(array_merge($EM_Event->fields, $EM_Location->fields)), get_option('dbem_events_default_order'));
  64. //Now, build orderby sql
  65. $orderby_sql = ( count($orderby) > 0 ) ? 'ORDER BY '. implode(', ', $orderby) : '';
  66. //Create the SQL statement and execute
  67. if( EM_MS_GLOBAL ){
  68. $selectors = ( $count ) ? 'COUNT(*)':$events_table.'.post_id, '.$events_table.'.blog_id';
  69. }else{
  70. $selectors = ( $count ) ? 'COUNT(*)':$events_table.'.post_id';
  71. }
  72. $sql = "
  73. SELECT $selectors FROM $events_table
  74. LEFT JOIN $locations_table ON {$locations_table}.location_id={$events_table}.location_id
  75. $where
  76. $orderby_sql
  77. $limit $offset
  78. ";
  79. //If we're only counting results, return the number of results
  80. if( $count ){
  81. return apply_filters('em_events_get_count', $wpdb->get_var($sql), $args);
  82. }
  83. $results = $wpdb->get_results( apply_filters('em_events_get_sql',$sql, $args), ARRAY_A);
  84. //If we want results directly in an array, why not have a shortcut here?
  85. if( $args['array'] == true ){
  86. return apply_filters('em_events_get_array',$results, $args);
  87. }
  88. //Make returned results EM_Event objects
  89. $results = (is_array($results)) ? $results:array();
  90. $events = array();
  91. if( EM_MS_GLOBAL ){
  92. foreach ( $results as $event ){
  93. $events[] = em_get_event($event['post_id'], $event['blog_id']);
  94. }
  95. }else{
  96. foreach ( $results as $event ){
  97. $events[] = em_get_event($event['post_id'], 'post_id');
  98. }
  99. }
  100. return apply_filters('em_events_get', $events, $args);
  101. }
  102. /**
  103. * Returns the number of events on a given date
  104. * @param $date
  105. * @return int
  106. */
  107. function count_date($date){
  108. global $wpdb;
  109. $table_name = EM_EVENTS_TABLE;
  110. $sql = "SELECT COUNT(*) FROM $table_name WHERE (event_start_date like '$date') OR (event_start_date <= '$date' AND event_end_date >= '$date');";
  111. return apply_filters('em_events_count_date', $wpdb->get_var($sql));
  112. }
  113. function count( $args = array() ){
  114. return apply_filters('em_events_count', self::get($args, true), $args);
  115. }
  116. /**
  117. * Will delete given an array of event_ids or EM_Event objects
  118. * @param unknown_type $id_array
  119. */
  120. function delete( $array ){
  121. global $wpdb;
  122. //Detect array type and generate SQL for event IDs
  123. $results = array();
  124. if( !empty($array) && @get_class(current($array)) != 'EM_Event' ){
  125. $events = self::get($array);
  126. }else{
  127. $events = $array;
  128. }
  129. $event_ids = array();
  130. foreach ($events as $EM_Event){
  131. $event_ids[] = $EM_Event->event_id;
  132. $results[] = $EM_Event->delete();
  133. }
  134. //TODO add better error feedback on events delete fails
  135. return apply_filters('em_events_delete', in_array(false, $results), $event_ids);
  136. }
  137. /**
  138. * Output a set of matched of events. You can pass on an array of EM_Events as well, in this event you can pass args in second param.
  139. * Note that you can pass a 'pagination' boolean attribute to enable pagination, default is enabled (true).
  140. * @param array $args
  141. * @param array $secondary_args
  142. * @return string
  143. */
  144. function output( $args ){
  145. global $EM_Event;
  146. $EM_Event_old = $EM_Event; //When looping, we can replace EM_Event global with the current event in the loop
  147. //Can be either an array for the get search or an array of EM_Event objects
  148. $func_args = func_get_args();
  149. $page = 1; //default
  150. if( !array_key_exists('page',$args) && !empty($_REQUEST['pno']) && is_numeric($_REQUEST['pno']) ){
  151. $page = $args['page'] = $_REQUEST['pno'];
  152. }
  153. if( is_object(current($args)) && get_class((current($args))) == 'EM_Event' ){
  154. $func_args = func_get_args();
  155. $events = $func_args[0];
  156. $args = (!empty($func_args[1]) && is_array($func_args[1])) ? $func_args[1] : array();
  157. $args = apply_filters('em_events_output_args', self::get_default_search($args), $events);
  158. $limit = ( !empty($args['limit']) && is_numeric($args['limit']) ) ? $args['limit']:false;
  159. $offset = ( !empty($args['offset']) && is_numeric($args['offset']) ) ? $args['offset']:0;
  160. $page = ( !empty($args['page']) && is_numeric($args['page']) ) ? $args['page']:$page;
  161. $events_count = count($events);
  162. }else{
  163. //Firstly, let's check for a limit/offset here, because if there is we need to remove it and manually do this
  164. $args = apply_filters('em_events_output_args', self::get_default_search($args) );
  165. $limit = ( !empty($args['limit']) && is_numeric($args['limit']) ) ? $args['limit']:false;
  166. $offset = ( !empty($args['offset']) && is_numeric($args['offset']) ) ? $args['offset']:0;
  167. $page = ( !empty($args['page']) && is_numeric($args['page']) ) ? $args['page']:$page;
  168. $args_count = $args;
  169. $args_count['limit'] = false;
  170. $args_count['offset'] = false;
  171. $args_count['page'] = false;
  172. $events_count = self::count($args_count);
  173. $events = self::get( $args );
  174. }
  175. //What format shall we output this to, or use default
  176. $format = ( empty($args['format']) ) ? get_option( 'dbem_event_list_item_format' ) : $args['format'] ;
  177. $output = "";
  178. $events = apply_filters('em_events_output_events', $events);
  179. if ( $events_count > 0 ) {
  180. foreach ( $events as $EM_Event ) {
  181. $output .= $EM_Event->output($format);
  182. }
  183. //Add headers and footers to output
  184. if( $format == get_option ( 'dbem_event_list_item_format' ) ){
  185. $format_header = ( get_option( 'dbem_event_list_item_format_header') == '' ) ? '':get_option ( 'dbem_event_list_item_format_header' );
  186. $format_footer = ( get_option ( 'dbem_event_list_item_format_footer' ) == '' ) ? '':get_option ( 'dbem_event_list_item_format_footer' );
  187. }else{
  188. $format_header = ( !empty($args['format_header']) ) ? $args['format_header']:'';
  189. $format_footer = ( !empty($args['format_footer']) ) ? $args['format_footer']:'';
  190. }
  191. $output = $format_header . $output . $format_footer;
  192. //Pagination (if needed/requested)
  193. if( !empty($args['pagination']) && !empty($limit) && $events_count > $limit ){
  194. //Show the pagination links (unless there's less than $limit events)
  195. $page_link_template = preg_replace('/(&|\?)pno=\d+/i','',$_SERVER['REQUEST_URI']);
  196. $page_link_template = em_add_get_params($page_link_template, array('pno'=>'%PAGE%'), false); //don't html encode, so em_paginate does its thing;
  197. $output .= apply_filters('em_events_output_pagination', em_paginate( $page_link_template, $events_count, $limit, $page), $page_link_template, $events_count, $limit, $page);
  198. }
  199. } else {
  200. $output = get_option ( 'dbem_no_events_message' );
  201. }
  202. //TODO check if reference is ok when restoring object, due to changes in php5 v 4
  203. $EM_Event = $EM_Event_old;
  204. $output = apply_filters('em_events_output', $output, $events, $args);
  205. return $output;
  206. }
  207. function can_manage($event_ids){
  208. global $wpdb;
  209. if( current_user_can('edit_others_events') ){
  210. return apply_filters('em_events_can_manage', true, $event_ids);
  211. }
  212. if( EM_Object::array_is_numeric($event_ids) ){
  213. $condition = implode(" OR event_id=", $event_ids);
  214. //we try to find any of these events that don't belong to this user
  215. $results = $wpdb->get_var("SELECT COUNT(*) FROM ". EM_EVENTS_TABLE ." WHERE event_owner != '". get_current_user_id() ."' event_id=$condition;");
  216. return apply_filters('em_events_can_manage', ($results == 0), $event_ids);
  217. }
  218. return apply_filters('em_events_can_manage', false, $event_ids);
  219. }
  220. function get_post_search($args = array(), $filter = false){
  221. if( !empty($_REQUEST['em_search']) && empty($args['search']) ) $_REQUEST['search'] = $_REQUEST['em_search'];
  222. if( !empty($_REQUEST['category']) && $_REQUEST['category'] == -1 ) $_REQUEST['category'] = $args['category'] = 0;
  223. $accepted_searches = apply_filters('em_accepted_searches', array('scope','search','category','country','state','region','town'), $args);
  224. foreach($_REQUEST as $post_key => $post_value){
  225. if( in_array($post_key, $accepted_searches) && !empty($post_value) ){
  226. if(is_array($post_value)){
  227. $post_value = implode(',',$post_value);
  228. }
  229. if($post_value != ',' ){
  230. $args[$post_key] = $post_value;
  231. }elseif( $post_value == ',' && $post_key == 'scope' ){
  232. $args['scope'] = get_option('dbem_events_page_scope');
  233. }
  234. }
  235. }
  236. if( $filter ){
  237. foreach($args as $arg_key => $arg_value){
  238. if( !in_array($arg_key, $accepted_searches) ){
  239. unset($args[$arg_key]);
  240. }
  241. }
  242. }
  243. return apply_filters('em_events_get_post_search', $args);
  244. }
  245. /* Overrides EM_Object method to apply a filter to result
  246. * @see wp-content/plugins/events-manager/classes/EM_Object#build_sql_conditions()
  247. */
  248. function build_sql_conditions( $args = array() ){
  249. $conditions = parent::build_sql_conditions($args);
  250. if( !empty($args['search']) ){
  251. $like_search = array('event_name',EM_EVENTS_TABLE.'.post_content','location_name','location_address','location_town','location_postcode','location_state','location_country');
  252. $conditions['search'] = "(".implode(" LIKE '%{$args['search']}%' OR ", $like_search). " LIKE '%{$args['search']}%')";
  253. }
  254. if( array_key_exists('status',$args) && is_numeric($args['status']) ){
  255. $null = ($args['status'] == 0) ? ' OR `event_status` = 0':'';
  256. $conditions['status'] = "(`event_status`={$args['status']}{$null} )";
  257. }elseif( empty($args['status']) || $args['status'] != 'all'){
  258. $conditions['status'] = "(`event_status` IS NOT NULL )"; //by default, we don't ever show deleted items
  259. }
  260. //private events
  261. if( empty($args['private']) ){
  262. $conditions['private'] = "(`event_private`=0)";
  263. }elseif( !empty($args['private_only']) ){
  264. $conditions['private_only'] = "(`event_private`=1)";
  265. }
  266. if( EM_MS_GLOBAL && !empty($args['blog']) ){
  267. if( is_numeric($args['blog']) ){
  268. if( is_main_site($args['blog']) ){
  269. $conditions['blog'] = "(".EM_EVENTS_TABLE.".blog_id={$args['blog']} OR ".EM_EVENTS_TABLE.".blog_id IS NULL)";
  270. }else{
  271. $conditions['blog'] = "(".EM_EVENTS_TABLE.".blog_id={$args['blog']})";
  272. }
  273. }else{
  274. if( !is_array($args['blog']) && preg_match('/^([\-0-9],?)+$/', $args['blog']) ){
  275. $conditions['blog'] = "(".EM_EVENTS_TABLE.".blog_id IN ({$args['blog']}) )";
  276. }elseif( is_array($args['blog']) && $this->array_is_numeric($args['blog']) ){
  277. $conditions['blog'] = "(".EM_EVENTS_TABLE.".blog_id IN (".implode(',',$args['blog']).") )";
  278. }
  279. }
  280. }
  281. if( $args['bookings'] === 'user' && is_user_logged_in()){
  282. //get bookings of user
  283. $EM_Person = new EM_Person(get_current_user_id());
  284. $booking_ids = $EM_Person->get_bookings(true);
  285. if( count($booking_ids) > 0 ){
  286. $conditions['bookings'] = "(event_id IN (SELECT event_id FROM ".EM_BOOKINGS_TABLE." WHERE booking_id IN (".implode(',',$booking_ids).")))";
  287. }else{
  288. $conditions['bookings'] = "(event_id = 0)";
  289. }
  290. }
  291. //post search
  292. if( !empty($args['post_id'])){
  293. if( is_array($args['post_id']) ){
  294. $conditions['post_id'] = "(".EM_EVENTS_TABLE.".post_id IN (".implode(',',$args['post_id'])."))";
  295. }else{
  296. $conditions['post_id'] = "(".EM_EVENTS_TABLE.".post_id={$args['post_id']})";
  297. }
  298. }
  299. return apply_filters( 'em_events_build_sql_conditions', $conditions, $args );
  300. }
  301. /* Overrides EM_Object method to apply a filter to result
  302. * @see wp-content/plugins/events-manager/classes/EM_Object#build_sql_orderby()
  303. */
  304. function build_sql_orderby( $args, $accepted_fields, $default_order = 'ASC' ){
  305. return apply_filters( 'em_events_build_sql_orderby', parent::build_sql_orderby($args, $accepted_fields, get_option('dbem_events_default_order')), $args, $accepted_fields, $default_order );
  306. }
  307. /*
  308. * Adds custom Events search defaults
  309. * @param array $array
  310. * @return array
  311. * @uses EM_Object#get_default_search()
  312. */
  313. function get_default_search( $array = array() ){
  314. $defaults = array(
  315. 'orderby' => get_option('dbem_events_default_orderby'),
  316. 'order' => get_option('dbem_events_default_order'),
  317. 'bookings' => false, //if set to true, only events with bookings enabled are returned
  318. 'status' => 1, //approved events only
  319. 'format_header' => '', //events can have custom html above the list
  320. 'format_footer' => '', //events can have custom html below the list
  321. 'town' => false,
  322. 'state' => false,
  323. 'country' => false,
  324. 'region' => false,
  325. 'blog' => get_current_blog_id(),
  326. 'private' => current_user_can('read_private_events'),
  327. 'private_only' => false,
  328. 'post_id' => false
  329. );
  330. if( EM_MS_GLOBAL && !is_admin() ){
  331. if( empty($array['blog']) && is_main_site() && get_site_option('dbem_ms_global_events') ){
  332. $array['blog'] = false;
  333. }
  334. }
  335. if( is_admin() ){
  336. //figure out default owning permissions
  337. $defaults['owner'] = !current_user_can('edit_others_events') ? get_current_user_id() : false;
  338. if( !array_key_exists('status', $array) && current_user_can('edit_others_events') ){
  339. $defaults['status'] = false; //by default, admins see pending and live events
  340. }
  341. }
  342. return apply_filters('em_events_get_default_search', parent::get_default_search($defaults,$array), $array, $defaults);
  343. }
  344. //TODO Implement object and interators for handling groups of events.
  345. public function rewind(){
  346. reset($this->events);
  347. }
  348. public function current(){
  349. $var = current($this->events);
  350. return $var;
  351. }
  352. public function key(){
  353. $var = key($this->events);
  354. return $var;
  355. }
  356. public function next(){
  357. $var = next($this->events);
  358. return $var;
  359. }
  360. public function valid(){
  361. $key = key($this->events);
  362. $var = ($key !== NULL && $key !== FALSE);
  363. return $var;
  364. }
  365. }
  366. ?>