· 10 years ago · Apr 14, 2016, 11:06 AM
1<?php
2a
3 /**********************************************************************
4 ***********************************************************************
5 COUPON FUNCTIONS
6 **********************************************************************/
7load_theme_textdomain('classifieds', get_template_directory() . '/languages');
8
9
10add_action( 'tgmpa_register', 'classifieds_requred_plugins' );
11function classifieds_requred_plugins(){
12 $plugins = array(
13 array(
14 'name' => esc_html__( 'Redux Options', 'classifieds' ),
15 'slug' => 'redux-framework',
16 'source' => get_template_directory() . '/lib/plugins/redux-framework.zip',
17 'required' => true,
18 'version' => '',
19 'force_activation' => false,
20 'force_deactivation' => false,
21 'external_url' => '',
22 ),
23 array(
24 'name' => esc_html__( 'Smeta', 'classifieds' ),
25 'slug' => 'smeta',
26 'source' => get_template_directory() . '/lib/plugins/smeta.zip',
27 'required' => true,
28 'version' => '',
29 'force_activation' => false,
30 'force_deactivation' => false,
31 'external_url' => '',
32 ),
33 array(
34 'name' => esc_html__( 'Social Connect', 'classifieds' ),
35 'slug' => 'social-connect',
36 'source' => get_template_directory() . '/lib/plugins/social-connect.zip',
37 'required' => true,
38 'version' => '',
39 'force_activation' => false,
40 'force_deactivation' => false,
41 'external_url' => '',
42 ),
43 array(
44 'name' => esc_html__( 'User Avatars', 'classifieds' ),
45 'slug' => 'wp-user-avatar',
46 'source' => get_template_directory() . '/lib/plugins/wp-user-avatar.zip',
47 'required' => true,
48 'version' => '',
49 'force_activation' => false,
50 'force_deactivation' => false,
51 'external_url' => '',
52 ),
53 array(
54 'name' => esc_html__( 'Classifieds CPT', 'classifieds' ),
55 'slug' => 'classifieds-cpt',
56 'source' => get_template_directory() . '/lib/plugins/classifieds-cpt.zip',
57 'required' => true,
58 'version' => '',
59 'force_activation' => false,
60 'force_deactivation' => false,
61 'external_url' => '',
62 ),
63 array(
64 'name' => esc_html__( 'Envato Market', 'classifieds' ),
65 'slug' => 'envato-market',
66 'source' => 'https://envato.github.io/wp-envato-market/dist/envato-market.zip',
67 'required' => false,
68 'version' => '',
69 'force_activation' => false,
70 'force_deactivation' => false,
71 'external_url' => 'https://envato.github.io/wp-envato-market/dist/envato-market.zip',
72 ),
73 );
74
75 /**
76 * Array of configuration settings. Amend each line as needed.
77 * If you want the default strings to be available under your own theme domain,
78 * leave the strings uncommented.
79 * Some of the strings are added into a sprintf, so see the comments at the
80 * end of each line for what each argument will be.
81 */
82 $config = array(
83 'domain' => 'classifieds',
84 'default_path' => '',
85 'parent_menu_slug' => 'themes.php',
86 'parent_url_slug' => 'themes.php',
87 'menu' => 'install-required-plugins',
88 'has_notices' => true,
89 'is_automatic' => false,
90 'message' => '',
91 );
92
93 tgmpa( $plugins, $config );
94}
95
96/*
97Check version of the theme and update if neccessary
98*/
99function classifieds_check_version(){
100 $current_version = 12;
101 $version = get_option( 'classifieds_version' );
102
103 $update_info = true;
104
105 if( empty( $version ) ){
106 $version = 0;
107 }
108 if( $version < 12 ){
109 /*move meta from postmeta to new table*/
110 global $wpdb;
111
112 $table_name = $wpdb->prefix.'custom_fields_meta';
113 if( $wpdb->get_var("SHOW TABLES LIKE '{$table_name}'") != $table_name ) {
114 if( is_admin() ){
115 $update_info = false;
116 $message = '<div class="error notice notice-success is-dismissible">
117 <p>'.esc_html__( 'You need to reinstall Classifieds Custom Post Types plugin', 'classifieds' ).'</p>
118 <button type="button" class="notice-dismiss"><span class="screen-reader-text">'.esc_html__( 'Dismiss this notice.', 'classifieds' ).'</span></button>
119 </div>';
120 set_transient( 'classifieds_update_notices', $message );
121 }
122 }
123 else{
124 $postmeta_results = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}custom_fields as cf LEFT JOIN {$wpdb->postmeta} AS postmeta ON cf.name = postmeta.meta_key WHERE postmeta.meta_key IS NOT NULL" );
125 if( !empty( $postmeta_results ) ){
126 foreach( $postmeta_results as $postmeta_result ){
127 $row = classifieds_add_post_meta( $postmeta_result->post_id, $postmeta_result->meta_key, $postmeta_result->meta_value );
128 $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->postmeta} WHERE meta_id = %d", $postmeta_result->meta_id ) );
129 }
130 }
131 }
132 }
133
134 if( $update_info ){
135 update_option( 'classifieds_version', $current_version );
136 }
137}
138add_action( 'init', 'classifieds_check_version' );
139
140
141if( !function_exists("classifieds_update_notices") ){
142function classifieds_update_notices(){
143 echo get_transient( 'classifieds_update_notices' );
144 delete_transient( 'classifieds_update_notices' );
145}
146add_action( 'admin_notices', 'classifieds_update_notices' );
147}
148
149/*
150Dashboard stats
151*/
152add_action( 'wp_dashboard_setup', 'classifieds_dashboard_overview' );
153function classifieds_dashboard_overview() {
154 add_meta_box('classifieds_stats_overall', esc_html__( 'Classifieds Stats', 'classifieds' ), 'classifieds_stats_overall', 'dashboard', 'side', 'high');
155}
156
157function classifieds_stats_overall(){
158 global $wpdb;
159 $featured = $wpdb->get_results("SELECT COUNT(*) AS count FROM {$wpdb->postmeta} WHERE meta_key = 'ad_featured' AND meta_value = 'yes'" );
160 $featured = $featured[0]->count;
161
162 $expired = $wpdb->get_results( $wpdb->prepare( "SELECT COUNT(*) AS count FROM {$wpdb->postmeta} WHERE meta_key = 'ad_expire' AND meta_value < %d", current_time( 'timestamp' ) ) );
163 $expired = $expired[0]->count;
164
165 $count_ads = wp_count_posts( 'ad' );
166 $pending = $count_ads->draft;
167 $approved = $count_ads->publish;
168 $basic = $pending + $approved - $featured;
169
170 $basic_ad_price = classifieds_get_option( 'basic_ad_price' );
171 $earnings_basic = $basic_ad_price * $basic;
172
173 $featured_ad_price = classifieds_get_option( 'featured_ad_price' );
174 $earnings_featured = $featured_ad_price * $featured;
175
176 echo '<ul class="classifieds-stats-list">
177 <li>
178 <span class="value"><a href="'.esc_url( admin_url( 'edit.php?post_type=ad' ) ).'">'.( $pending + $approved ).'</a></span>
179 '.esc_html__( 'Total Ads', 'classifieds' ).'
180 </li>
181 <li>
182 <span class="value">'.classifieds_format_price_number( $earnings_basic + $earnings_featured ).'</span>
183 '.esc_html__( 'Total Ads Earnings', 'classifieds' ).'
184 </li>
185 <li>
186 <span class="value"><a href="'.esc_url( admin_url( 'edit.php?post_type=ad&ad_featured=yes' ) ).'">'.$featured.'</a></span>
187 '.esc_html__( 'Featured Ads', 'classifieds' ).'
188 </li>
189 <li>
190 <span class="value">'.classifieds_format_price_number( $earnings_featured ).'</span>
191 '.esc_html__( 'Featured Ads Earnings', 'classifieds' ).'
192 </li>
193 <li>
194 <span class="value"><a href="'.esc_url( admin_url( 'edit.php?post_type=ad&ad_featured=no' ) ).'">'.$basic.'</a></span>
195 '.esc_html__( 'Not Featured Ads', 'classifieds' ).'
196 </li>
197 <li>
198 <span class="value">'.classifieds_format_price_number( $earnings_basic ).'</span>
199 '.esc_html__( 'Not Featured Ads Earnings', 'classifieds' ).'
200 </li>
201 <li>
202 <span class="value"><a href="'.esc_url( admin_url( 'edit.php?post_type=ad&ad_expire=yes' ) ).'">'.$expired.'</a></span>
203 '.esc_html__( 'Expired Ads', 'classifieds' ).'
204 </li>
205 <li>
206 <span class="value"><a href="'.esc_url( admin_url( 'edit.php?post_type=ad&post_status=draft' ) ).'">'.$pending.'</a></span>
207 '.esc_html__( 'Pending Approval Ads', 'classifieds' ).'
208 </li>
209 </ul>';
210}
211
212/*
213Filter ads by custom fields
214*/
215function classifieds_posts_filter( $query ){
216 global $wpdb;
217 if ( is_admin() && isset($_GET['post_type']) && $_GET['post_type'] == 'ad') {
218 if( isset( $_GET['ad_featured'] ) ){
219 $query->set('meta_query', array(
220 array(
221 'key' => 'ad_featured',
222 'value' => $_GET['ad_featured'],
223 'compare' => '='
224 )
225 ));
226 }
227 else if( isset( $_GET['ad_expire'] ) ){
228 $query->set('meta_query', array(
229 array(
230 'key' => 'ad_expire',
231 'value' => current_time('timestamp'),
232 'compare' => '<='
233 )
234 ));
235 }
236 }
237 return $query;
238}
239add_action( 'pre_get_posts', 'classifieds_posts_filter' );
240
241/*
242Add filter to list of ads in the backend
243*/
244function classifieds_additional_filters_ad($views){
245 global $post_type_object, $wpdb;
246 $post_type = $post_type_object->name;
247
248
249 $expired = $wpdb->get_results( $wpdb->prepare( "SELECT COUNT(*) AS count FROM {$wpdb->postmeta} WHERE meta_key = 'ad_expire' AND meta_value < %d", current_time( 'timestamp' ) ) );
250 $expired = $expired[0]->count;
251
252 $views['today'] = '<a href="edit.php?post_type='.esc_attr__( $post_type ).'&ad_expire=yes" class="'.( isset( $_GET['ad_expire'] ) ? 'current' : '' ).'">'.esc_html__('Expired','classifieds').'</a> ('.$expired.')';
253
254 return $views;
255}
256add_filter( 'views_edit-ad', 'classifieds_additional_filters_ad');
257
258
259if (!isset($content_width)){
260 $content_width = 1920;
261}
262
263/*
264Add meta box on the side of the ad to show its status
265 */
266function classifieds_ad_status_meta_box() {
267 add_meta_box(
268 'classifieds_ad_status',
269 esc_html__( 'Ad Status', 'classifieds' ),
270 'classifieds_ad_status',
271 'ad',
272 'side',
273 'high'
274 );
275}
276add_action( 'add_meta_boxes', 'classifieds_ad_status_meta_box' );
277
278/*
279Print status of the add in the meta box
280 */
281function classifieds_ad_status( $post ) {
282 classifieds_get_ad_status( $post->ID );
283}
284
285
286/*
287Create custom submenu item under Products
288*/
289function classifieds_create_menu_items(){
290 add_submenu_page('edit.php?post_type=custom_field', esc_html__('Import / Export','classifieds'), esc_html__('Import / Export','classifieds'), 'edit_posts', 'cf-import', 'classifieds_cf_import_export');
291}
292add_action('admin_menu', 'classifieds_create_menu_items');
293
294/*
295Add import / export feature to custom fields
296*/
297function classifieds_cf_import_export(){
298 include( classifieds_load_path( 'includes/cf-import.php' ) );
299}
300
301/*
302Export CF values
303*/
304function classifieds_export_cf_values(){
305 global $wpdb;
306 $export = array();
307 $cfs = get_posts(array(
308 'post_type' => 'custom_field',
309 'posts_per_page' => -1,
310 ));
311
312 if( !empty( $cfs ) ){
313 $rows = array();
314 foreach( $cfs as $cf ){
315 $rows['post_'.$cf->ID] = array(
316 'cf_meta' => array(
317 'post_name' => $cf->post_name,
318 'post_title' => $cf->post_title,
319 'post_status' => $cf->post_status,
320 'fields_for' => get_post_meta( $cf->ID, 'fields_for', true )
321 ),
322 'fields' => array()
323 );
324 $results = $wpdb->get_results(
325 $wpdb->prepare(
326 "SELECT * FROM {$wpdb->prefix}custom_fields WHERE post_id = %d",
327 $cf->ID
328 )
329 );
330 foreach( $results as $res ){
331 $rows['post_'.$cf->ID]['fields'][] = $res;
332 }
333 }
334
335 $custom_fields_meta = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}custom_fields_meta" );
336
337 $export['custom_fields'] = $rows;
338 $export['custom_fields_meta'] = $custom_fields_meta;
339 }
340
341 echo '<textarea class="cf-import">'.json_encode( $export ).'</textarea>';
342}
343
344/*
345Import CF values
346*/
347function classifieds_import_cf_values(){
348 global $wpdb;
349 $cf_values = isset( $_POST['cf_values'] ) ? $_POST['cf_values'] : '';
350 if( !empty( $cf_values ) ){
351 $cf_values = json_decode( stripslashes($cf_values), true );
352 if( !empty( $cf_values ) ){
353 /* first import custom values */
354 $custom_fields = $cf_values['custom_fields'];
355 if( !empty( $custom_fields ) ){
356 foreach( $custom_fields as $row ){
357 $post_id = wp_insert_post(array(
358 'post_name' => $row['cf_meta']['post_name'],
359 'post_title' => $row['cf_meta']['post_title'],
360 'post_status' => $row['cf_meta']['post_status'],
361 'post_type' => 'custom_field'
362 ));
363 update_post_meta( $post_id, 'fields_for', $row['cf_meta']['fields_for'] );
364 if( !empty( $row['fields'] ) ){
365 foreach( $row['fields'] as $field_row ){
366 $info = $wpdb->query(
367 $wpdb->prepare(
368 "INSERT INTO {$wpdb->prefix}custom_fields VALUES( '', %d, %s, %s, %s, %s, %s, %d )",
369 $post_id,
370 $field_row['name'],
371 $field_row['label'],
372 $field_row['type'],
373 $field_row['field_values'],
374 $field_row['child_of_value'],
375 $field_row['parent']
376 )
377 );
378 }
379 }
380 }
381 }
382
383 /* import meta values */
384 $custom_fields_meta = $cf_values['custom_fields_meta'];
385 if( !empty( $custom_fields_meta ) ){
386 foreach( $custom_fields_meta as $row ){
387 $info = $wpdb->query(
388 $wpdb->prepare(
389 "INSERT INTO {$wpdb->prefix}custom_fields_meta VALUES( '', %d, %s, %s )",
390 $row['post_id'],
391 $row['name'],
392 $row['val']
393 )
394 );
395 }
396 }
397
398 if( !empty( $info ) ){
399 ?>
400 <div class="updated notice notice-success is-dismissible">
401 <p><?php esc_html_e( 'Import process finished', 'classifieds' ) ?></p>
402 <button type="button" class="notice-dismiss"><span class="screen-reader-text"><?php esc_html_e( 'Dismiss this notice.', 'classifieds' ) ?></span></button>
403 </div>
404 <?php
405 }
406 else{
407 ?>
408 <div class="error notice notice-success is-dismissible">
409 <p><?php esc_html_e( 'Import process failed', 'classifieds' ) ?></p>
410 <button type="button" class="notice-dismiss"><span class="screen-reader-text"><?php esc_html_e( 'Dismiss this notice.', 'classifieds' ) ?></span></button>
411 </div>
412 <?php
413 }
414 }
415 }
416}
417
418
419/*
420Save meta value for the post in the new table
421*/
422function classifieds_add_post_meta( $post_id, $meta_key, $meta_value ){
423 global $wpdb;
424 $return = $wpdb->insert(
425 $wpdb->prefix.'custom_fields_meta',
426 array(
427 'post_id' => $post_id,
428 'name' => $meta_key,
429 'val' => $meta_value
430 ),
431 array(
432 '%d',
433 '%s',
434 '%s'
435 )
436 );
437}
438
439/*
440Read meta from custom table
441*/
442function classifieds_get_post_meta( $post_id, $name ){
443 global $wpdb;
444 $res = $wpdb->get_results( $wpdb->prepare( "SELECT val FROM {$wpdb->prefix}custom_fields_meta WHERE post_id = %d AND name = %s", $post_id, $name ) );
445 if( !empty( $res[0] ) ){
446 return $res[0]->val;
447 }
448 else{
449 return '';
450 }
451}
452
453/*
454Do shortcodes in the excerpt
455*/
456add_filter('the_excerpt', 'do_shortcode');
457
458/*
459Check if field exists in the child theme and if so load it
460*/
461function classifieds_load_path( $path ){
462 if ( file_exists( get_stylesheet_directory() . '/' . $path )) {
463 return get_stylesheet_directory() . '/' . $path;
464 } else {
465 return get_template_directory() . '/' . $path;
466 }
467}
468
469/*
470Check if field exists in the child theme and if so load it
471*/
472function classifieds_load_uri_path( $path ){
473 if ( file_exists( get_stylesheet_directory_uri() . '/' . $path )) {
474 include( get_stylesheet_directory_uri() . '/' . $path );
475 } else {
476 require( get_template_directory_url() . '/' . $path );
477 }
478}
479
480/*
481Register theme sidebars
482*/
483function classifieds_widgets_init(){
484
485 register_sidebar(array(
486 'name' => esc_html__('Blog Sidebar', 'classifieds') ,
487 'id' => 'sidebar-blog',
488 'before_widget' => '<div class="widget white-block %2$s">',
489 'after_widget' => '</div>',
490 'before_title' => '<h4>',
491 'after_title' => '</h4>',
492 'description' => esc_html__('Appears on the right side of the blog.', 'classifieds')
493 ));
494
495 register_sidebar(array(
496 'name' => esc_html__('Page Sidebar Right', 'classifieds') ,
497 'id' => 'sidebar-right',
498 'before_widget' => '<div class="widget white-block %2$s">',
499 'after_widget' => '</div>',
500 'before_title' => '<h4>',
501 'after_title' => '</h4>',
502 'description' => esc_html__('Appears on the right side of the page.', 'classifieds')
503 ));
504
505 register_sidebar(array(
506 'name' => esc_html__('Page Sidebar Left', 'classifieds') ,
507 'id' => 'sidebar-left',
508 'before_widget' => '<div class="widget white-block %2$s">',
509 'after_widget' => '</div>',
510 'before_title' => '<h4>',
511 'after_title' => '</h4>',
512 'description' => esc_html__('Appears on the left side of the page.', 'classifieds')
513 ));
514
515 register_sidebar(array(
516 'name' => esc_html__('Search Sidebar', 'classifieds') ,
517 'id' => 'sidebar-search',
518 'before_widget' => '<div class="widget white-block %2$s">',
519 'after_widget' => '</div>',
520 'before_title' => '<h4>',
521 'after_title' => '</h4>',
522 'description' => esc_html__('Appears on the left side of the search page.', 'classifieds')
523 ));
524
525 register_sidebar(array(
526 'name' => esc_html__('Single Ad Sidebar', 'classifieds') ,
527 'id' => 'sidebar-ad',
528 'before_widget' => '<div class="widget white-block %2$s">',
529 'after_widget' => '</div>',
530 'before_title' => '<h4>',
531 'after_title' => '</h4>',
532 'description' => esc_html__('Appears on the right side of the single ad page bellow the ad data.', 'classifieds')
533 ));
534
535 register_sidebar(array(
536 'name' => esc_html__('Bottom Sidebar 1', 'classifieds') ,
537 'id' => 'sidebar-bottom-1',
538 'before_widget' => '<div class="widget white-block %2$s">',
539 'after_widget' => '</div>',
540 'before_title' => '<h4>',
541 'after_title' => '</h4>',
542 'description' => esc_html__('Appears at the bottom of the page.', 'classifieds')
543 ));
544
545 register_sidebar(array(
546 'name' => esc_html__('Bottom Sidebar 2', 'classifieds') ,
547 'id' => 'sidebar-bottom-2',
548 'before_widget' => '<div class="widget white-block %2$s">',
549 'after_widget' => '</div>',
550 'before_title' => '<h4>',
551 'after_title' => '</h4>',
552 'description' => esc_html__('Appears at the bottom of the page.', 'classifieds')
553 ));
554
555 register_sidebar(array(
556 'name' => esc_html__('Bottom Sidebar 3', 'classifieds') ,
557 'id' => 'sidebar-bottom-3',
558 'before_widget' => '<div class="widget white-block %2$s">',
559 'after_widget' => '</div>',
560 'before_title' => '<h4>',
561 'after_title' => '</h4>',
562 'description' => esc_html__('Appears at the bottom of the page.', 'classifieds')
563 ));
564
565 register_sidebar(array(
566 'name' => esc_html__('Shop Sidebar', 'classifieds') ,
567 'id' => 'shop-sidebar',
568 'before_widget' => '<div class="widget white-block %2$s">',
569 'after_widget' => '</div>',
570 'before_title' => '<h4>',
571 'after_title' => '</h4>',
572 'description' => esc_html__('Used for the widget area on shop page.', 'classifieds')
573 ));
574
575 $mega_menu_sidebars = classifieds_get_option( 'mega_menu_sidebars' );
576 if( empty( $mega_menu_sidebars ) ){
577 $mega_menu_sidebars = 5;
578 }
579
580 for( $i=1; $i <= $mega_menu_sidebars; $i++ ){
581 register_sidebar(array(
582 'name' => esc_html__('Mega Menu Sidebar ', 'classifieds').$i,
583 'id' => 'mega-menu-'.$i,
584 'before_widget' => '<li class="widget white-block %2$s">',
585 'after_widget' => '</li>',
586 'before_title' => '<h4>',
587 'after_title' => '</h4>',
588 'description' => esc_html__('This will be shown as the dropdown menu in the navigation.', 'classifieds')
589 ));
590 }
591}
592
593add_action('widgets_init', 'classifieds_widgets_init');
594
595/*
596Update title of the page on search
597*/
598function classifieds_wp_title( $title, $sep ) {
599 global $paged, $page, $classifieds_slugs;
600
601 if ( is_feed() ){
602 return $title;
603 }
604 if( is_page() && get_page_template_slug( get_the_ID() ) == 'page-tpl_my_profile.php' ){
605 return $title;
606 }
607
608 $keyword = get_query_var( $classifieds_slugs['keyword'] );
609 if( !empty( $keyword ) ){
610 $title = str_replace( '_', ' ', urldecode( $keyword ) )." $sep ".$title;
611 }
612
613 $location = get_query_var( $classifieds_slugs['location'] );
614 if( !empty( $location ) ){
615 $title = $location." $sep ".$title;
616 }
617
618 $ad_category = get_query_var( $classifieds_slugs['category'] );
619 if( !empty( $ad_category ) ){
620 $term = get_term_by( 'slug', $ad_category, 'ad-category' );
621 $title = $term->name." $sep ".$title;
622 }
623
624 return $title;
625}
626add_filter( 'wp_title', 'classifieds_wp_title', 10, 2 );
627
628/*
629Set direction of the site
630*/
631function classifieds_set_direction() {
632 global $wp_locale, $wp_styles;
633
634 $_user_id = get_current_user_id();
635 $direction = classifieds_get_option( 'direction' );
636 if( empty( $direction ) ){
637 $direction = 'ltr';
638 }
639
640 if ( $direction ) {
641 update_user_meta( $_user_id, 'rtladminbar', $direction );
642 } else {
643 $direction = get_user_meta( $_user_id, 'rtladminbar', true );
644 if ( false === $direction )
645 $direction = isset( $wp_locale->text_direction ) ? $wp_locale->text_direction : 'ltr' ;
646 }
647
648 $wp_locale->text_direction = $direction;
649 if ( ! is_a( $wp_styles, 'WP_Styles' ) ) {
650 $wp_styles = new WP_Styles();
651 }
652 $wp_styles->text_direction = $direction;
653}
654add_action( 'init', 'classifieds_set_direction' );
655
656
657/*
658Get URL based on the tempalte which is being used
659*/
660function classifieds_get_permalink_by_tpl( $template_name ){
661 $page = get_pages(array(
662 'meta_key' => '_wp_page_template',
663 'meta_value' => $template_name . '.php'
664 ));
665 if(!empty($page)){
666 return get_permalink( $page[0]->ID );
667 }
668 else{
669 return "javascript:;";
670 }
671}
672
673/*
674generate random hash fgor the register
675*/
676function classifieds_confirm_hash( $length = 100 ) {
677 $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
678 $random_string = '';
679 for ($i = 0; $i < $length; $i++) {
680 $random_string .= $characters[rand(0, strlen($characters) - 1)];
681 }
682 return $random_string;
683}
684
685/*
686Get list of registered image sizes
687*/
688function classifieds_get_image_sizes(){
689 $list = array();
690 $sizes = get_intermediate_image_sizes();
691 foreach( $sizes as $size ){
692 $list[$size] = $size;
693 }
694
695 return $list;
696}
697
698/*
699Get status of the ad
700*/
701
702function classifieds_get_ad_status( $post_id ){
703 $ad_expire = get_post_meta( $post_id, 'ad_expire', true );
704 $is_expired = false;
705 if( current_time( 'timestamp' ) > $ad_expire ){
706 $is_expired = true;
707 }
708
709 if( get_post_status( $post_id ) == 'draft' ){
710 esc_html_e( 'PENDING', 'classifieds' );
711 }
712 else if( $is_expired ){
713 esc_html_e( 'EXPIRED', 'classifieds' );
714 }
715 else{
716 echo esc_html__( 'LIVE UNTIL: ', 'classifieds' ).date( 'M j, Y - H:i', $ad_expire );
717 }
718}
719
720/*
721Add custom columns on the ads listing
722*/
723function classifieds_custom_offer_columns($columns) {
724 $columns =
725 array_slice($columns, 0, count($columns) - 1, true) +
726 array(
727 "ad_category" => esc_html__( 'Category', 'classifieds' ),
728 "ad_price" => esc_html__( 'Price', 'classifieds' ),
729 "ad_views" => esc_html__( 'Views', 'classifieds' ),
730 "ad_expire" => esc_html__( 'Status', 'classifieds' ),
731 ) +
732 array_slice($columns, count($columns) - 1, count($columns) - 1, true) ;
733 return $columns;
734}
735add_filter( 'manage_edit-ad_columns', 'classifieds_custom_offer_columns' );
736
737/* Populate additional column */
738function classifieds_custom_offer_columns_populate( $column, $post_id ) {
739 if( $column == 'ad_category' ){
740 $list = array();
741 $terms = get_the_terms( $post_id, 'ad-category' );
742 if( !empty( $terms ) ){
743 foreach( $terms as $term ){
744 $list[] = $term->name;
745 }
746 }
747
748 echo join( $list, ', ' );
749 }
750 else if( $column == 'ad_price' ){
751 echo classifieds_get_price( $post_id );
752 }
753 else if( $column == 'ad_views' ){
754 echo get_post_meta( $post_id, 'ad_views', true );
755 }
756 else if( $column == 'ad_expire' ){
757 classifieds_get_ad_status( $post_id );
758 }
759}
760add_action( 'manage_ad_posts_custom_column', 'classifieds_custom_offer_columns_populate', 10, 2 );
761
762/*
763Add custom column on the users listing page in the backend
764*/
765function classifieds_active_column($columns) {
766 $columns['active'] = esc_html__( 'Activation Status', 'classifieds' );
767 $columns['basic_ads'] = esc_html__( 'Basic Ads', 'classifieds' );
768 $columns['featured_ads'] = esc_html__( 'Featured Ads', 'classifieds' );
769 return $columns;
770}
771add_filter('manage_users_columns', 'classifieds_active_column');
772
773/* Populate additional column */
774function classifieds_active_column_content( $value, $column_name, $user_id ){
775 if ( 'active' == $column_name ){
776 $usermeta = get_user_meta( $user_id, 'user_active_status', true );
777 if( empty( $usermeta ) || $usermeta == "active" ){
778 return esc_html__( 'Activated', 'classifieds' );
779 }
780 else{
781 return esc_html__( 'Need Confirmation', 'classifieds' );
782 }
783 }
784 else if ( 'basic_ads' == $column_name ){
785 $posts = get_posts(array(
786 'post_type' => 'ad',
787 'posts_per_page' => '-1',
788 'author' => $user_id,
789 'post_status' => 'publish',
790 'meta_query' => array(
791 array(
792 'key' => 'ad_featured',
793 'value' => 'no',
794 ),
795 )
796 ));
797 $basic_ad_price = classifieds_get_option( 'basic_ad_price' );
798
799 $dispaly = sizeof( $posts );
800 if( !empty( $basic_ad_price ) ){
801 $basic_ad_price = $basic_ad_price * sizeof( $posts );
802 $dispaly .= ' - '.classifieds_format_price_number( $basic_ad_price );
803 }
804 return $dispaly;
805 }
806 else if ( 'featured_ads' == $column_name ){
807 $posts = get_posts(array(
808 'post_type' => 'ad',
809 'posts_per_page' => '-1',
810 'author' => $user_id,
811 'post_status' => 'publish',
812 'meta_query' => array(
813 array(
814 'key' => 'ad_featured',
815 'value' => 'yes',
816 ),
817 )
818 ));
819 $featured_ad_price = classifieds_get_option( 'featured_ad_price' );
820
821 $dispaly = sizeof( $posts );
822 if( !empty( $featured_ad_price ) ){
823 $featured_ad_price = $featured_ad_price * sizeof( $posts );
824 $dispaly .= ' - '.classifieds_format_price_number( $featured_ad_price );
825 }
826
827 return $dispaly;
828 }
829 return $value;
830}
831add_action('manage_users_custom_column', 'classifieds_active_column_content', 10, 3);
832
833/*
834Add additional fields on the edit user screen in the backend
835*/
836function classifieds_edit_user_status( $user ){
837 $user_active_status = get_user_meta( $user->ID, 'user_active_status', true );
838 $city = get_user_meta( $user->ID, 'city', true );
839 $phone_number = get_user_meta( $user->ID, 'phone_number', true );
840 $cover_image = get_user_meta( $user->ID, 'cover_image', true );
841 $is_verified = classifieds_is_verified( $user->ID );
842 $avatar = get_user_meta( $user->ID, 'avatar', true );
843 $twitter = get_user_meta( $user->ID, 'twitter', true );
844 $linkedin = get_user_meta( $user->ID, 'linkedin', true );
845 $instagram = get_user_meta( $user->ID, 'instagram', true );
846 $facebook = get_user_meta( $user->ID, 'facebook', true );
847 $google = get_user_meta( $user->ID, 'google', true );
848 ?>
849 <h3><?php esc_html_e( 'User Info', 'classifieds' ) ?></h3>
850
851 <table class="form-table">
852 <tr>
853 <th><label for="user_active_status"><?php esc_html_e( 'User Status', 'classifieds' ); ?></label></th>
854 <td>
855 <select name="user_active_status" id="user_active_status">
856 <option <?php echo !empty( $user_active_status ) && $user_active_status != 'active' ? 'selected="selected"' : '' ?> value="inactive"><?php esc_html_e( 'Inactive', 'classifieds' ) ?></option>
857 <option <?php echo empty( $user_active_status ) || $user_active_status == 'active' ? 'selected="selected"' : '' ?> value="active"><?php esc_html_e( 'Active', 'classifieds' ) ?></option>
858 </select>
859 </td>
860 </tr>
861 <tr>
862 <th><label for="is_verified"><?php esc_html_e( 'User Is Verified Poster?', 'classifieds' ); ?></label></th>
863 <td>
864 <select name="is_verified" id="is_verified">
865 <option <?php echo !$is_verified ? esc_attr__( 'selected="selected"' ) : '' ?> value="no"><?php esc_html_e( 'No', 'classifieds' ) ?></option>
866 <option <?php echo $is_verified ? esc_attr__( 'selected="selected"' ) : '' ?> value="yes"><?php esc_html_e( 'Yes', 'classifieds' ) ?></option>
867 </select>
868 </td>
869 </tr>
870 <tr>
871 <th><label for="city"><?php esc_html_e( 'City', 'classifieds' ); ?></label></th>
872 <td>
873 <input type="text" name="city" id="city" value="<?php echo esc_attr__( $city ) ?>">
874 </td>
875 </tr>
876 <tr>
877 <th><label for="phone_number"><?php esc_html_e( 'Phone Number', 'classifieds' ); ?></label></th>
878 <td>
879 <input type="text" name="phone_number" id="phone_number" value="<?php echo esc_attr__( $phone_number ) ?>"/>
880 </td>
881 </tr>
882 <tr>
883 <th><label><?php esc_html_e( 'Cover Image', 'classifieds' ); ?></label></th>
884 <td>
885 <div class="image-wrap">
886 <?php if( !empty( $cover_image ) ){
887 echo wp_get_attachment_image( $cover_image, 'thumbnail' );
888 echo '<a href="javascript:;" class="button remove-image">X</a>';
889 }?>
890 </div>
891 <a href="javascript:;" class="button set-image"><?php esc_html_e( 'Change Cover', 'classifieds' ) ?></a>
892 <input type="hidden" name="cover_image" id="cover_image" value="<?php echo esc_attr__( $cover_image ) ?>" class="form-control">
893 </td>
894 </tr>
895 <tr>
896 <th><label for="twitter"><?php esc_html_e( 'Twitter', 'classifieds' ); ?></label></th>
897 <td>
898 <input type="text" name="twitter" id="twitter" value="<?php echo esc_attr__( $twitter ) ?>">
899 </td>
900 </tr>
901 <tr>
902 <th><label for="linkedin"><?php esc_html_e( 'Linkedin', 'classifieds' ); ?></label></th>
903 <td>
904 <input type="text" name="linkedin" id="linkedin" value="<?php echo esc_attr__( $linkedin ) ?>">
905 </td>
906 </tr>
907 <tr>
908 <th><label for="instagram"><?php esc_html_e( 'Instagram', 'classifieds' ); ?></label></th>
909 <td>
910 <input type="text" name="instagram" id="instagram" value="<?php echo esc_attr__( $instagram ) ?>">
911 </td>
912 </tr>
913 <tr>
914 <th><label for="facebook"><?php esc_html_e( 'Facebook', 'classifieds' ); ?></label></th>
915 <td>
916 <input type="text" name="facebook" id="facebook" value="<?php echo esc_attr__( $facebook ) ?>">
917 </td>
918 </tr>
919 <tr>
920 <th><label for="google"><?php esc_html_e( 'Google+', 'classifieds' ); ?></label></th>
921 <td>
922 <input type="text" name="google" id="google" value="<?php echo esc_attr__( $google ) ?>">
923 </td>
924 </tr>
925 </table>
926 <?php
927}
928add_action( 'show_user_profile', 'classifieds_edit_user_status' );
929add_action( 'edit_user_profile', 'classifieds_edit_user_status' );
930
931/*
932Save custom values i the user edit screen on the backend
933*/
934function classifieds_save_user_meta( $user_id ){
935 update_user_meta( $user_id,'user_active_status', sanitize_text_field($_POST['user_active_status']) );
936 update_user_meta( $user_id,'city', sanitize_text_field($_POST['city']) );
937 update_user_meta( $user_id,'phone_number', sanitize_text_field($_POST['phone_number']) );
938 update_user_meta( $user_id,'is_verified', sanitize_text_field($_POST['is_verified']) );
939 update_user_meta( $user_id,'cover_image', sanitize_text_field($_POST['cover_image']) );
940 update_user_meta( $user_id,'avatar', sanitize_text_field($_POST['avatar']) );
941 update_user_meta( $user_id,'twitter', sanitize_text_field($_POST['twitter']) );
942 update_user_meta( $user_id,'linkedin', sanitize_text_field($_POST['linkedin']) );
943 update_user_meta( $user_id,'instagram', sanitize_text_field($_POST['instagram']) );
944 update_user_meta( $user_id,'facebook', sanitize_text_field($_POST['facebook']) );
945 update_user_meta( $user_id,'google', sanitize_text_field($_POST['google']) );
946}
947add_action( 'personal_options_update', 'classifieds_save_user_meta' );
948add_action( 'edit_user_profile_update', 'classifieds_save_user_meta' );
949
950
951/*
952Disable admin bar for all users except the admin
953*/
954function classifieds_remove_admin_bar() {
955 $user_ID = get_current_user_id();
956 $user_agent = get_user_meta( $user_ID, 'user_agent', true );
957 if (!current_user_can('administrator') && !is_admin() && ( !$user_agent || $user_agent == 'no' ) ) {
958 show_admin_bar(false);
959 }
960}
961add_action('after_setup_theme', 'classifieds_remove_admin_bar');
962
963
964/*
965Default values of the theme optins
966*/
967function classifieds_defaults( $id ){
968 $defaults = array(
969 'site_logo' => array( 'url' => '' ),
970 'site_logo_padding' => '',
971 'site_navigation_padding'=> '',
972 'enable_sticky' => 'no',
973 'my_profile_looks' => esc_html__( 'My Profile', 'classifieds' ),
974 'login_looks' => esc_html__( 'Login', 'classifieds' ),
975 'direction' => 'ltr',
976 'trans_ad' => 'ad',
977 'trans_ad_category' => 'ad-category',
978 'trans_ad_tag' => 'ad-tag',
979 'trans_category' => 'category',
980 'trans_tag' => 'tag',
981 'trans_keyword' => 'keyword',
982 'trans_location' => 'location',
983 'trans_longitude' => 'longitude',
984 'trans_latitude' => 'latitude',
985 'trans_radius' => 'radius',
986 'trans_view' => 'view',
987 'trans_sortby' => 'sortby',
988 'trans_subpage' => 'subpage',
989 'show_search_bar' => 'no',
990 'radius_search_units' => 'km',
991 'radius_default' => '300',
992 'radius_options' => '',
993 'empty_search_location' => '',
994 'mega_menu_sidebars' => '5',
995 'mega_menu_min_height' => '',
996 'show_clients' => 'no',
997 'footer_copyrights' => '',
998 'show_subscribe' => 'no',
999 'footer_subscribe_text' => '',
1000 'footer_subscribe_subtext' => '',
1001 'show_woocommerce_sidebar' => 'yes',
1002 'products_per_page' => '9',
1003 'contact_mail' => 'contact_form_subject',
1004 'contact_map' => '',
1005 'contact_map_scroll_zoom' => 'no',
1006 'contact_map_zoom' => '',
1007 'all_categories_sortby' => 'name',
1008 'all_categories_sort' => 'asc',
1009 'show_map_on_home' => 'no',
1010 'home_map_cache' => 'yes',
1011 'home_map_ads' => '',
1012 'home_map_ads_source' => 'all',
1013 'home_map_zoom' => '',
1014 'home_slider' => '',
1015 'ads_per_page' => '12',
1016 'author_ads_per_page' => '12',
1017 'author_profile_ads_per_page' => '12',
1018 'ads_for_verified' => '10',
1019 'similar_ads' => '2',
1020 'ads_default_view' => 'grid',
1021 'video_image' => '',
1022 'ads_search_layout' => 'style-top',
1023 'ads_advanced_search' => 'yes',
1024 'ads_max_videos' => '10',
1025 'ads_max_images' => '10',
1026 'image_placeholder' => '',
1027 'ad_terms' => '',
1028 'basic_ad_price' => '0',
1029 'basic_ad_title' => '',
1030 'basic_ad_subtitle' => '',
1031 'featured_ad_price' => '5',
1032 'featured_ad_title' => '',
1033 'featured_ad_subtitle' => '',
1034 'ad_lasts_for' => '30',
1035 'email_sender' => '',
1036 'name_sender' => '',
1037 'new_offer_email' => '',
1038 'ad_messaging' => '',
1039 'ad_approve_message' => '',
1040 'ad_decline_message' => '',
1041 'registration_message' => '',
1042 'registration_subject' => '',
1043 'lost_password_message' => '',
1044 'lost_password_subject' => '',
1045 'send_expire_notice' => '',
1046 'expire_template' => '',
1047 'ad_expire_subject' => '',
1048 'unit' => '',
1049 'main_unit_abbr' => '',
1050 'unit_position' => '',
1051 'paypal_mode' => '',
1052 'paypal_username' => '',
1053 'paypal_password' => '',
1054 'paypal_signature' => '',
1055 'stripe_pk_client_id' => '',
1056 'stripe_sk_client_id' => '',
1057 'skrill_owner_mail' => '',
1058 'skrill_secret_word' => '',
1059 'bank_account_name' => '',
1060 'bank_name' => '',
1061 'bank_account_number' => '',
1062 'bank_sort_number' => '',
1063 'bank_iban_number' => '',
1064 'bank_bic_swift_number' => '',
1065 'mollie_id' => '',
1066 'ideal_mode' => 'live',
1067 'payu_merchant_key' => '',
1068 'payu_merchant_salt' => '',
1069 'payu_mode' => '',
1070 'mail_chimp_api' => '',
1071 'mail_chimp_list_id' => '',
1072 'body_links_color' => '#208ee6',
1073 'theme_font' => 'Montserrat',
1074 'header_bg_color' => '#1e3843',
1075 'navigation_font_color' => '#fff',
1076 'navigation_font_color_hvr' => '#7dcffb',
1077 'submit_btn_bg_color' => '#208ee6',
1078 'submit_btn_font_color' => '#fff',
1079 'submit_btn_bg_color_hvr' => '#177ed0',
1080 'submit_btn_font_color_hvr' => '#fff',
1081 'footer_bg_color' => '#273642',
1082 'footer_font_color' => '#fff',
1083 'footer_link_color' => '#fff',
1084 'footer_link_color_hvr' => '#59b453',
1085 'copyright_bg_color' => '#1d2a34',
1086 'copyright_font_color' => '#49535b',
1087 'copyright_link_color' => '#fff',
1088 'copyright_link_color_hvr' => '#59b453',
1089 'btn1_bg_color' => '#59b453',
1090 'btn1_font_color' => '#fff',
1091 'btn1_bg_color_hvr' => '#4ca247',
1092 'btn1_font_color_hvr' => '#fff',
1093 'btn2_bg_color' => '#208ee6',
1094 'btn2_font_color' => '#fff',
1095 'btn2_bg_color_hvr' => '#177ed0',
1096 'btn2_font_color_hvr' => '#fff',
1097 'expired_badge_bg_color' => '#ebb243',
1098 'expired_badge_font_color' => '#fff',
1099 'pending_badge_bg_color' => '#49a3eb',
1100 'pending_badge_font_color' => '#fff',
1101 'live_badge_bg_color' => '#78c273',
1102 'live_badge_font_color' => '#fff',
1103 'not_paid_badge_bg_color' => '#f66a45',
1104 'not_paid_badge_font_color' => '#fff',
1105 'off_badge_bg_color' => '#bbc4cb',
1106 'off_badge_font_color' => '#fff',
1107 'ad_form_btn_bg_color' => '#7dcffb',
1108 'ad_form_btn_font_color' => '#fff',
1109 'ad_form_btn_bg_color_hvr' => '#5fc4fa',
1110 'ad_form_btn_font_color_hvr' => '#fff',
1111 'single_ad_price_size' => '26px',
1112 'home_map_geolocation' => 'no',
1113 'all_categories_count' => 'no'
1114 );
1115
1116 if( isset( $defaults[$id] ) ){
1117 return $defaults[$id];
1118 }
1119 else{
1120
1121 return '';
1122 }
1123}
1124
1125/*
1126Get theme option based on the ID
1127*/
1128function classifieds_get_option($id){
1129 global $classifieds_options;
1130 if( isset( $classifieds_options[$id] ) ){
1131 $value = $classifieds_options[$id];
1132 if( isset( $value ) ){
1133 return apply_filters( 'classifieds_get_options', $value, $id );
1134 }
1135 else{
1136 return apply_filters( 'classifieds_get_options', '', $id );
1137 }
1138 }
1139 else{
1140 return apply_filters( 'classifieds_get_options', classifieds_defaults( $id ), $id );
1141 }
1142}
1143
1144/*
1145Basic settigns of the theme
1146*/
1147function classifieds_setup(){
1148 add_theme_support('automatic-feed-links');
1149 add_theme_support( 'woocommerce' );
1150 add_theme_support( "title-tag" );
1151 add_theme_support('html5', array(
1152 'comment-form',
1153 'comment-list'
1154 ));
1155 register_nav_menu('top-navigation', esc_html__('Top Navigation', 'classifieds'));
1156
1157 add_theme_support('post-thumbnails');
1158
1159 set_post_thumbnail_size(848, 477, true);
1160 if (function_exists('add_image_size')){
1161 add_image_size( 'classifieds-ad-box', 263, 172, true );
1162 add_image_size( 'classifieds-ad-box-alt', 110, 110, true );
1163 add_image_size( 'classifieds-map', 80, 80, true );
1164 add_image_size( 'classifieds-avatar', 90, 90, true );
1165 add_image_size( 'classifieds-similar-ads', 100, 100, true );
1166 add_image_size( 'classifieds-ad-single', 500, 400, true );
1167 add_image_size( 'classifieds-ad-owl-thumb', 100, 100, true );
1168 add_image_size( 'classifieds-ad-thumb', 205, 165, true );
1169 add_image_size( 'classifieds-ad-category-bg-thumb', 555, 250, true );
1170 add_image_size( 'classifieds-ad-box-bug', 525, 343, true );
1171 add_image_size( 'classifieds-ad-box-all', 557, 170, true );
1172 }
1173
1174 add_theme_support('custom-header');
1175 add_theme_support('custom-background');
1176 add_theme_support('post-formats',array( 'aside', 'gallery', 'link', 'image', 'quote', 'status', 'video', 'audio', 'chat' ));
1177 add_editor_style();
1178}
1179add_action('after_setup_theme', 'classifieds_setup');
1180
1181/*
1182Load google fonts properly
1183*/
1184function classifieds_load_google_font( $font_family ){
1185 $font_url = '';
1186 if ( 'off' !== _x( 'on', 'Google font: on or off', 'studio' ) ) {
1187 $font_url = add_query_arg( 'family', urlencode( $font_family.':100,300,400,700,900,100italic,300italic,400italic,700italic,900italic' ), "//fonts.googleapis.com/css" );
1188 }
1189 return $font_url;
1190}
1191
1192/*
1193Enqueue styles and scripts for the theme
1194*/
1195function classifieds_scripts_styles(){
1196 $template_slug = get_page_template_slug();
1197 $protocol = is_ssl() ? 'https' : 'http';
1198
1199 wp_enqueue_style( 'classifieds-awesome', get_template_directory_uri() . '/css/font-awesome.min.css' );
1200 wp_enqueue_style( 'classifieds-bootstrap', get_template_directory_uri() . '/css/bootstrap.min.css' );
1201 wp_enqueue_style( 'classifieds-carousel', get_template_directory_uri() . '/css/owl.carousel.css' );
1202
1203 $theme_font = classifieds_get_option( 'theme_font' );
1204
1205 if( !empty( $theme_font ) ){
1206 wp_enqueue_style( 'classifieds-navigation-font', classifieds_load_google_font( $theme_font ), array(), '1.0.0' );
1207 }
1208
1209 wp_enqueue_script( 'classifieds-googlemap', $protocol.'://maps.googleapis.com/maps/api/js?libraries=places&sensor=false', array('jquery'), false, true );
1210 wp_enqueue_script( 'classifieds-bootstrap-js', get_template_directory_uri() . '/js/bootstrap.min.js', array('jquery'), false, true );
1211 wp_enqueue_script( 'classifieds-bootstrap-multilevel-js', get_template_directory_uri() . '/js/bootstrap-dropdown-multilevel.js', array('jquery'), false, true );
1212
1213 if( $template_slug == 'page-tpl_my_profile.php' ){
1214 wp_enqueue_media();
1215 wp_enqueue_script('classifieds-image-uploads', get_template_directory_uri() . '/js/image-uploader.js', array('jquery'), false, true );
1216 wp_enqueue_script('classifieds-gmap-submit', get_template_directory_uri() . '/js/gmap.js', array('jquery'), false, true );
1217 wp_enqueue_script('classifieds-custom-fields', get_template_directory_uri() . '/js/custom-fields.js', array('jquery'), false, true );
1218 wp_enqueue_script( 'classifieds-stripe', 'https://checkout.stripe.com/checkout.js', false, false, true );
1219
1220 }
1221
1222 if( $template_slug == 'page-tpl_home_page.php' || $template_slug == 'page-tpl_search_page.php' ){
1223 wp_enqueue_script( 'classifieds-markerclusterer_compiled', get_template_directory_uri() . '/js/markerclusterer_compiled.js', array('jquery'), false, true );
1224 wp_enqueue_script( 'classifieds-infobox', get_template_directory_uri() . '/js/infobox.js', array('jquery'), false, true );
1225 }
1226
1227 if (is_singular() && comments_open() && get_option('thread_comments')){
1228 wp_enqueue_script('comment-reply');
1229 }
1230
1231 /* OWL CAROUSEL */
1232 wp_enqueue_script( 'classifieds-carousel', get_template_directory_uri() . '/js/owl.carousel.min.js', array('jquery'), false, true );
1233 wp_enqueue_script( 'classifieds-responsive-slides', get_template_directory_uri() . '/js/responsiveslides.min.js', array('jquery'), false, true );
1234
1235 /* SELECT 2 */
1236 wp_enqueue_style( 'classifieds-select2', get_template_directory_uri() . '/js/select2/select2.css' );
1237 wp_enqueue_script( 'classifieds-select2', get_template_directory_uri() . '/js/select2/select2.min.js', array('jquery'), false, true );
1238
1239 /* MASONRY */
1240 wp_enqueue_script( 'classifieds-imagesloaded', get_template_directory_uri() . '/js/imagesloaded.js', false, false, true );
1241 wp_enqueue_script( 'classifieds-masonry', get_template_directory_uri() . '/js/masonry.js', false, false, true );
1242
1243 /* CACHE */
1244 wp_enqueue_script( 'classifieds-cache', get_template_directory_uri() . '/js/cache.js', array('jquery'), false, true );
1245
1246 /* MAGNIFIC POPUP */
1247 wp_enqueue_style( 'classifieds-magnific-popup', get_template_directory_uri() . '/css/magnific-popup.css' );
1248 wp_enqueue_script( 'classifieds-magnific-popup', get_template_directory_uri() . '/js/jquery.magnific-popup.min.js', array('jquery'), false, true );
1249
1250 wp_enqueue_script( 'classifieds-custom', get_template_directory_uri() . '/js/custom.js', array('jquery'), false, true );
1251 wp_localize_script( 'classifieds-custom', 'classifieds_data', array(
1252 'url' => get_template_directory_uri(),
1253 'home_map_geolocation' => is_front_page() ? classifieds_get_option( 'home_map_geolocation' ) : 'no',
1254 'home_map_geo_zoom' => classifieds_get_option( 'home_map_geo_zoom' ),
1255 'contact_map_zoom' => classifieds_get_option( 'contact_map_zoom' ),
1256 'restrict_country' => classifieds_get_option( 'restrict_country' ),
1257 'home_map_zoom' => classifieds_get_option( 'home_map_zoom' ),
1258 'map_price' => classifieds_get_option( 'home_map_show_price' ),
1259 'empty_search_location' => classifieds_get_option('empty_search_location'),
1260 'ads_max_videos' => classifieds_get_option( 'ads_max_videos' ),
1261 'ads_max_images' => classifieds_get_option( 'ads_max_images' ),
1262 ) );
1263
1264}
1265add_action('wp_enqueue_scripts', 'classifieds_scripts_styles', 2 );
1266
1267/*
1268Load style based on the theme option settings
1269*/
1270function classifieds_load_color_schema(){
1271 /* LOAD MAIN STYLE */
1272 wp_enqueue_style('classifieds-style', get_stylesheet_uri() , array());
1273 ob_start();
1274 include( classifieds_load_path( 'css/main-color.css.php' ) );
1275 $custom_css = ob_get_contents();
1276 ob_end_clean();
1277 wp_add_inline_style( 'classifieds-style', $custom_css );
1278}
1279add_action('wp_enqueue_scripts', 'classifieds_load_color_schema', 4 );
1280
1281/*
1282Load resuorces which are avaialabe in the admin backend
1283*/
1284function classifieds_admin_resources(){
1285 global $post;
1286 wp_enqueue_style( 'classifieds-awesome', get_template_directory_uri() . '/css/font-awesome.min.css' );
1287 if( ( isset( $_GET['post_type'] ) && $_GET['post_type'] == 'custom_field' ) || ( isset( $post ) && $post->post_type == 'custom_field' ) ){
1288 wp_enqueue_script( 'classifieds-admin-custom-fields', get_template_directory_uri() . '/js/admin.js', false, false, true );
1289 }
1290
1291 if( ( isset( $_GET['post_type'] ) && $_GET['post_type'] == 'ad' ) || ( isset( $post ) && $post->post_type == 'ad' ) ){
1292 wp_enqueue_script( 'classifieds-ad-custom-fields', get_template_directory_uri() . '/js/custom-fields.js', false, false, true );
1293 }
1294
1295 wp_enqueue_style( 'wp-color-picker' );
1296 wp_enqueue_script( 'wp-color-picker' );
1297 wp_enqueue_script( 'jquery-ui-sortable' );
1298 wp_enqueue_script( 'jquery-ui-dialog' );
1299
1300 wp_enqueue_script( 'classifieds-cache', get_template_directory_uri() . '/js/cache.js', array('jquery'), false, true );
1301
1302 wp_enqueue_style('classifieds-jquery-ui', get_template_directory_uri() . '/css/jquery-ui.css' );
1303 wp_enqueue_script('jquery-ui-sortable');
1304 wp_enqueue_style('classifieds-shortcodes-style', get_template_directory_uri() . '/css/admin.css' );
1305 wp_enqueue_script('classifieds-multidropdown', get_template_directory_uri() . '/js/multidropdown.js', false, false, true);
1306 wp_enqueue_script('classifieds-image-uploader', get_template_directory_uri() . '/js/image-uploader.js', false, false, true);
1307 wp_enqueue_media();
1308}
1309add_action( 'admin_enqueue_scripts', 'classifieds_admin_resources' );
1310
1311
1312/*
1313Add adminajax url on the page
1314*/
1315function classifieds_custom_head(){
1316 echo '<script type="text/javascript">var ajaxurl = \'' . admin_url('admin-ajax.php') . '\';</script>';
1317}
1318add_action('wp_head', 'classifieds_custom_head');
1319
1320function classifieds_smeta_images( $meta_key, $post_id, $default ){
1321 if(class_exists('SM_Frontend')){
1322 global $sm;
1323 return $result = $sm->sm_get_meta($meta_key, $post_id);
1324 }
1325 else{
1326 return $default;
1327 }
1328}
1329
1330/*
1331Get list of the post types
1332*/
1333function classifieds_get_custom_list( $post_type, $args = array(), $orderby = '', $direction = 'right' ){
1334 $post_array = array();
1335 $args = array( 'post_type' => $post_type, 'post_status' => 'publish', 'posts_per_page' => -1 ) + $args;
1336 if( !empty( $orderby ) ){
1337 $args['orderby'] = $orderby;
1338 $args['order'] = 'ASC';
1339 }
1340 $posts = get_posts( $args );
1341
1342 foreach( $posts as $post ){
1343 if( $direction == 'right' ){
1344 $post_array[$post->ID] = $post->post_title;
1345 }
1346 else{
1347 $post_array[$post->post_title] = $post->ID;
1348 }
1349 }
1350
1351 return $post_array;
1352}
1353
1354/*
1355Get taxonomy list
1356*/
1357function classifieds_get_custom_tax_list( $taxonomy, $direction = 'right', $hide_empty = true, $field = 'slug' ){
1358 $terms = get_terms( $taxonomy, array( 'hide_empty' => $hide_empty ));
1359 $term_list = array();
1360 if( !empty( $terms ) ){
1361 foreach( $terms as $term ){
1362 if( $direction == 'right' ){
1363 $term_list[$term->$field] = $term->name;
1364 }
1365 else{
1366 $term_list[$term->name] = $term->$field;
1367 }
1368 }
1369 }
1370
1371 return $term_list;
1372}
1373
1374/*
1375Get all custom fields
1376*/
1377function classifieds_get_custom_fields( $post_id ){
1378 global $wpdb;
1379
1380 $fields = $wpdb->get_results(
1381 $wpdb->prepare(
1382 "SELECT * FROM {$wpdb->prefix}custom_fields WHERE post_id = %d AND parent = 0 ORDER BY field_id",
1383 $post_id
1384 )
1385 );
1386
1387 return $fields;
1388}
1389
1390/*
1391Get all custom subfields
1392*/
1393function classifieds_get_custom_subfields( $post_id, $field_id ){
1394 global $wpdb;
1395
1396 $subfields = $wpdb->get_results(
1397 $wpdb->prepare(
1398 "SELECT * FROM {$wpdb->prefix}custom_fields WHERE post_id = %d AND parent = %d ORDER BY field_id",
1399 $post_id,
1400 $field_id
1401 )
1402 );
1403
1404 return $subfields;
1405}
1406
1407/*
1408Create select boxes
1409*/
1410function classifieds_generate_select( $field, $selected, $hidden = true ){
1411 $select = '<li class="'.( $hidden ? 'hidden' : '' ).'"><div class="'.( empty( $field->child_of_value ) ? '' : 'custom-select-wrap '.str_replace('|', '-', $field->child_of_value) ).'">';
1412 $select .= '<label for="'.esc_attr__( $field->name ).'">'.$field->label.'</label>
1413 <select name="cf_'.esc_attr__( $field->name ).'" id="'.esc_attr__( $field->name ).'" class="form-control '.( empty( $field->child_of_value ) ? 'custom-select-change' : '' ).'">';
1414 $select .= '<option value="">'.esc_html__( 'Select', 'classifieds' ).'</option>';
1415 $values = explode( "\n", $field->field_values );
1416 if( !empty( $values ) ){
1417 foreach( $values as $value ){
1418 if( !empty( $value ) ){
1419 $temp = explode( "|", $value );
1420 $select .= '<option value="'.esc_attr__( $temp[0] ).'" '.( $selected == $temp[0] ? 'selected="selected"' : '' ).'>'.$temp[1].'</option>';
1421 }
1422 }
1423 }
1424 $select .= '</select>';
1425 $select .= '</div></li>';
1426
1427 return $select;
1428}
1429
1430/*
1431Create input field
1432*/
1433function classifieds_generate_input( $field, $value ){
1434 return '<label for="'.esc_attr__( $field->name ).'">'.$field->label.'</label>
1435 <input type="text" name="cf_'.esc_attr__( $field->name ).'" id="'.esc_attr__( $field->name ).'" class="form-control" value="'.( !empty( $value ) ? esc_attr__( $value ) : '' ).'"/>';
1436}
1437
1438/*
1439Add meta box for the custom fields custom post type
1440*/
1441function classifieds_add_meta_box_custom_fields() {
1442 add_meta_box(
1443 'classifieds_custom_meta',
1444 esc_html__( 'Custom Fields Data', 'classifieds' ),
1445 'classifieds_populate_meta_box_custom_fields',
1446 'custom_field'
1447 );
1448}
1449add_action( 'add_meta_boxes', 'classifieds_add_meta_box_custom_fields' );
1450
1451
1452/*
1453Populate meta box for the custom fields custompo st type
1454*/
1455function classifieds_populate_meta_box_custom_fields( $post ) {
1456 global $wpdb;
1457 $current_fields = '';
1458
1459 $fields = classifieds_get_custom_fields( $post->ID );
1460 $counter = 0;
1461 if( !empty( $fields ) ){
1462 foreach( $fields as $field ){
1463 $subfields_html = '';
1464 if( $field->type == 'select' ){
1465 $subfields = classifieds_get_custom_subfields( $post->ID, $field->field_id );
1466 if( !empty( $subfields ) ){
1467 foreach( $subfields as $subfield ){
1468 $subgroup_name = $subfield->name;
1469 $subgroup_label = $subfield->label;
1470 $values_args = explode('|', $subfield->child_of_value);
1471 $subfields_html .= '
1472 <div class="subgroups_field '.esc_attr__( $values_args[0] ).'">
1473 <a href="javascript:;" class="remove_subgroup button">X</a>
1474 <label for="cf_subgroup_label['.$counter.']['.$subfield->child_of_value.']">'.esc_html__( 'Values for', 'classifieds' ).' <span>'.$values_args[1].'</span></label>
1475 <textarea name="cf_field['.$counter.'][cf_subfield]['.$subfield->child_of_value.']" id="cf_subgroup_label['.$counter.']['.$subfield->child_of_value.']">'.$subfield->field_values.'</textarea>
1476 <p class="description">'.esc_html__( 'Input values one per line in form VALUE|LABEL. LABEL must not contain spaces,and special signs.', 'classifieds' ).'</p>
1477 </div>
1478 ';
1479 }
1480 }
1481 }
1482 $current_fields .= '
1483 <div class="cf_add_field_block">
1484 <div class="clearfix">
1485 <div class="pull-left">
1486 <div class="cf_title">'.$field->label.'</div>
1487 </div>
1488 <div class="pull-right">
1489 <div class="acf_field_actions">
1490 <a href="javascript:;" class="button remove-field">
1491 <i class="fa fa-times"></i>
1492 </a>
1493 </div>
1494 </div>
1495 </div>
1496 <div class="cf_body">
1497 <div class="cf_basic">
1498 <div class="cf_form_group">
1499 <label for="cf_name['.$counter.']">'.esc_html__('Field Name', 'classifieds').'</label>
1500 <input type="text" name="cf_field['.$counter.'][cf_name]" id="cf_name['.$counter.']" value="'.esc_attr__( $field->name ).'" />
1501 <input type="hidden" name="cf_field['.$counter.'][cf_old_name]" value="'.esc_attr__( $field->name ).'" />
1502 <p class="description">'.esc_html__( 'Input name of the field. It must not contain empty spaces and special chars.', 'classifieds' ).'</p>
1503 </div>
1504 <div class="cf_form_group">
1505 <label for="cf_label['.$counter.']">'.esc_html__('Field Label', 'classifieds').'</label>
1506 <input type="text" name="cf_field['.$counter.'][cf_label]" id="cf_label['.$counter.']" value="'.esc_attr__( $field->label ).'" />
1507 <p class="description">'.esc_html__( 'Input label for the field.', 'classifieds' ).'</p>
1508 </div>
1509 <div class="cf_form_group">
1510 <label for="cf_type['.$counter.']">'.esc_html__('Field Type', 'classifieds').'</label>
1511 <select name="cf_field['.$counter.'][cf_type]" id="cf_type['.$counter.']">
1512 <option value="input">'.esc_html__( 'Input Field', 'classifieds' ).'</option>
1513 <option value="select" '.( ( $field->type == 'select' ) ? 'selected="selected"' : '' ).'>'.esc_html__( 'Select Field', 'classifieds' ).'</option>
1514 </select>
1515 <p class="description">'.esc_html__( 'Select type of the field.', 'classifieds' ).'</p>
1516 </div>
1517 </div>
1518 <div class="cf_is_input">
1519
1520 </div>
1521 <div class="cf_is_select '.( ( $field->type == 'select' ) ? '' : 'hidden' ).'">
1522
1523 <label for="cf_select_values">'.esc_html__('Select Box Options', 'classifieds').'</label>
1524 <textarea name="cf_field['.$counter.'][cf_select_values]" id="cf_field['.$counter.'][cf_select_values]" class="select_values">'.$field->field_values.'</textarea>
1525 <p class="description">'.esc_html__( 'Input values one per line in form VALUE|LABEL', 'classifieds' ).'</p>
1526
1527 <a href="javascript:;" class="button create_subgroups '.( empty( $subfields ) ? '' : 'hidden' ).'">'.esc_html__( 'Make Subgroups', 'classifieds' ).'</a>
1528 <a href="javascript:;" class="button update_subgroups '.( empty( $subfields ) ? 'hidden' : '' ).'">'.esc_html__( 'Update Subgroups', 'classifieds' ).'</a>
1529 <a href="javascript:;" class="button remove_subgroups"><i class="fa fa-times"></i></a>
1530 <input type="hidden" class="has_subgroup" name="cf_field['.$counter.'][has_subgroups]" value="'.( !empty( $subfields ) ? '1' : '0' ).'">
1531
1532 <div class="cf_select_subgroup '.( !empty( $subfields ) ? '' : 'hidden' ).'">
1533 <label for="cf_subgroup_name['.$counter.']">'.esc_html__( 'Subgroup Name', 'classifieds' ).'</label>
1534 <input type="text" name="cf_field['.$counter.'][cf_subfield_name]" id="cf_subgroup_name['.$counter.']" value="'.esc_attr__( !empty( $subgroup_name ) ? $subgroup_name : '' ).'" />
1535 <p class="description">'.esc_html__( 'Input name of the subfield. It must not contain empty spaces and special chars.', 'classifieds' ).'</p>
1536
1537 <input type="hidden" name="cf_field['.$counter.'][cf_subfield_old_name]" value="'.esc_attr__( !empty( $subgroup_name ) ? $subgroup_name : '' ).'" />
1538 <label for="cf_subgroup_label['.$counter.']">'.esc_html__( 'Subgroup Label', 'classifieds' ).'</label>
1539 <input type="text" name="cf_field['.$counter.'][cf_subfield_label]" id="cf_subgroup_label['.$counter.']" value="'.esc_attr__( !empty( $subgroup_label ) ? $subgroup_label : '' ).'" />
1540 <p class="description">'.esc_html__( 'Input label for the subfield.', 'classifieds' ).'</p>
1541
1542 <div class="subgroups_field hidden">
1543 <a href="javascript:;" class="remove_subgroup button">X</a>
1544 <label for="cf_subgroup_label['.$counter.'][valuex]">'.esc_html__( 'Values for', 'classifieds' ).' <span>[labelx]</span></label>
1545 <textarea name="cf_field['.$counter.'][cf_subfield][valuex]" id="cf_subgroup_label['.$counter.'][valuex]"></textarea>
1546 <p class="description">'.esc_html__( 'Input values one per line in form VALUE|LABEL. LABEL must not contain spaces,and special signs.', 'classifieds' ).'</p>
1547 </div>
1548 </div>
1549
1550 <div class="subgroups_holder">
1551 '.$subfields_html.'
1552 </div>
1553 </div>
1554 </div>
1555 </div>
1556 ';
1557 $counter++;
1558 }
1559 }
1560
1561 $basic = '
1562 <div class="cf_add_field_block hidden">
1563 <div class="clearfix">
1564 <div class="pull-left">
1565 <div class="cf_title"></div>
1566 </div>
1567 <div class="pull-right">
1568 <div class="acf_field_actions">
1569 <a href="javascript:;" class="button remove-field">
1570 <i class="fa fa-times"></i>
1571 </a>
1572 </div>
1573 </div>
1574 </div>
1575 <div class="cf_body">
1576 <div class="cf_basic">
1577 <div class="cf_form_group">
1578 <label for="cf_name[x]">'.esc_html__('Field Name', 'classifieds').'</label>
1579 <input type="text" name="cf_field[x][cf_name]" id="cf_name[x]" />
1580 <p class="description">'.esc_html__( 'Input name of the field. It must not contain empty spaces and special chars.', 'classifieds' ).'</p>
1581 </div>
1582 <div class="cf_form_group">
1583 <label for="cf_label[x]">'.esc_html__('Field Label', 'classifieds').'</label>
1584 <input type="text" name="cf_field[x][cf_label]" id="cf_label[x]" />
1585 <p class="description">'.esc_html__( 'Input label for the field.', 'classifieds' ).'</p>
1586 </div>
1587 <div class="cf_form_group">
1588 <label for="cf_type[x]">'.esc_html__('Field Type', 'classifieds').'</label>
1589 <select name="cf_field[x][cf_type]" id="cf_type[x]">
1590 <option value="input">'.esc_html__( 'Input Field', 'classifieds' ).'</option>
1591 <option value="select">'.esc_html__( 'Select Field', 'classifieds' ).'</option>
1592 </select>
1593 <p class="description">'.esc_html__( 'Select type of the field.', 'classifieds' ).'</p>
1594 </div>
1595 </div>
1596 <div class="cf_is_input">
1597
1598 </div>
1599 <div class="cf_is_select hidden">
1600
1601 <label for="cf_select_values">'.esc_html__('Select Box Options', 'classifieds').'</label>
1602 <textarea name="cf_field[x][cf_select_values]" id="cf_field[x][cf_select_values]" class="select_values"></textarea>
1603 <p class="description">'.esc_html__( 'Input values one per line in form VALUE|LABEL', 'classifieds' ).'</p>
1604
1605 <a href="javascript:;" class="button create_subgroups">'.esc_html__( 'Make Subgroups', 'classifieds' ).'</a>
1606 <a href="javascript:;" class="button update_subgroups hidden">'.esc_html__( 'Update Subgroups', 'classifieds' ).'</a>
1607 <a href="javascript:;" class="button remove_subgroups"><i class="fa fa-times"></i></a>
1608 <input type="hidden" class="has_subgroup" name="cf_field[x][has_subgroups]" value="0">
1609
1610 <div class="cf_select_subgroup hidden">
1611 <label for="cf_subgroup_name[x]">'.esc_html__( 'Subgroup Name', 'classifieds' ).'</label>
1612 <input type="text" name="cf_field[x][cf_subfield_name]" id="cf_subgroup_name[x]"/>
1613 <p class="description">'.esc_html__( 'Input name of the subfield. It must not contain empty spaces and special chars.', 'classifieds' ).'</p>
1614
1615 <label for="cf_subgroup_label[x]">'.esc_html__( 'Subgroup Label', 'classifieds' ).'</label>
1616 <input type="text" name="cf_field[x][cf_subfield_label]" id="cf_subgroup_label[x]"/>
1617 <p class="description">'.esc_html__( 'Input label for the subfield.', 'classifieds' ).'</p>
1618
1619 <div class="subgroups_field hidden">
1620 <a href="javascript:;" class="remove_subgroup button">X</a>
1621 <label for="cf_subgroup_label[x][valuex]">'.esc_html__( 'Values for', 'classifieds' ).' <span>[labelx]</span></label>
1622 <textarea name="cf_field[x][cf_subfield][valuex]" id="cf_subgroup_label[x][valuex]"></textarea>
1623 <p class="description">'.esc_html__( 'Input values one per line in form VALUE|LABEL. LABEL must not contain spaces,and special signs.', 'classifieds' ).'</p>
1624 </div>
1625 </div>
1626
1627 <div class="subgroups_holder">
1628 </div>
1629 </div>
1630 </div>
1631 </div>
1632
1633 '.$current_fields.'
1634
1635 <a href="javascript:;" class="button button-primary cf_add_new_field">'.esc_html__( 'Add New Field', 'classifieds' ).'</a>
1636 ';
1637
1638 echo $basic;
1639
1640}
1641
1642/*
1643Save custom values
1644*/
1645function classifieds_save_custom_fields_meta( $post_id ) {
1646 // If this is an autosave, our form has not been submitted, so we don't want to do anything.
1647 if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
1648 return;
1649 }
1650
1651 // Check the user's permissions.
1652 if ( isset( $_POST['post_type'] ) && 'custom_field' == $_POST['post_type'] ) {
1653
1654 if ( ! current_user_can( 'edit_page', $post_id ) ) {
1655 return;
1656 }
1657
1658 } else {
1659
1660 if ( ! current_user_can( 'edit_post', $post_id ) ) {
1661 return;
1662 }
1663 }
1664
1665 /* OK, it's safe for us to save the data now. */
1666
1667 // Make sure that it is set.
1668 if ( ! isset( $_POST['cf_field'] ) ) {
1669 return;
1670 }
1671
1672 // Sanitize user input.
1673 $custom_meta = sanitize_text_field( $_POST['classifieds_custom_meta'] );
1674
1675 // Update the meta field in the database.
1676 //update_post_meta( $post_id, 'classifieds_custom_meta', $custom_meta );
1677 global $wpdb;
1678 $wpdb->query(
1679 $wpdb->prepare(
1680 "DELETE FROM {$wpdb->prefix}custom_fields WHERE post_id = %d",
1681 $post_id
1682 )
1683 );
1684
1685
1686 foreach( $_POST['cf_field'] as $key => $field ){
1687 if( $key !== 'x' ){
1688 $wpdb->query(
1689 $wpdb->prepare(
1690 "INSERT INTO {$wpdb->prefix}custom_fields VALUES( '', %d, %s, %s, %s, %s, %s, %d )",
1691 $post_id,
1692 $field['cf_name'],
1693 $field['cf_label'],
1694 $field['cf_type'],
1695 $field['cf_select_values'],
1696 '',
1697 0
1698 )
1699 );
1700
1701 if( $field['has_subgroups'] == '1' ){
1702 $parent = $wpdb->insert_id;
1703 foreach( $field['cf_subfield'] as $subkey => $subvalues ){
1704 if( $subkey !== 'valuex' ){
1705 $wpdb->query(
1706 $wpdb->prepare(
1707 "INSERT INTO {$wpdb->prefix}custom_fields VALUES( '', %d, %s, %s, %s, %s, %s, %d )",
1708 $post_id,
1709 $field['cf_subfield_name'],
1710 $field['cf_subfield_label'],
1711 'select',
1712 $subvalues,
1713 $subkey,
1714 $parent
1715 )
1716 );
1717 }
1718 }
1719 }
1720
1721 if( !empty( $field['cf_old_name'] ) ){
1722 $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->prefix}custom_fields_meta SET name = %s WHERE name = %s", $field['cf_name'], $field['cf_old_name'] ) );
1723 }
1724
1725 if( !empty( $field['cf_subfield_old_name'] ) ){
1726 $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->prefix}custom_fields_meta SET name = %s WHERE name = %s", $field['cf_subfield_name'], $field['cf_subfield_old_name'] ) );
1727 }
1728 }
1729 }
1730}
1731add_action( 'save_post', 'classifieds_save_custom_fields_meta' );
1732
1733
1734function classifieds_delete_custom_fields_meta( $post_id ){
1735 global $wpdb, $post_type;
1736
1737 if( $post_type == 'custom_field' ){
1738 /* delete values from ads */
1739 $wpdb->query(
1740 $wpdb->prepare(
1741 "DELETE postmeta.* FROM {$wpdb->prefix}custom_fields AS cf LEFT JOIN {$wpdb->prefix}custom_fields_meta AS postmeta ON cf.name = postmeta.name WHERE cf.post_id = %d"
1742 , $post_id )
1743 );
1744 /* delete from the custom table */
1745 $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}custom_fields WHERE post_id = %d", $post_id ) );
1746 }
1747 else if( $post_type == 'ad' ){
1748 $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}custom_fields_meta WHERE post_id = %d", $post_id ) );
1749 }
1750}
1751add_action( 'delete_post', 'classifieds_delete_custom_fields_meta' );
1752/*
1753Add custom fields to the post types
1754*/
1755if( !function_exists('classifieds_custom_meta_boxes') ){
1756function classifieds_custom_meta_boxes(){
1757 $post_meta_standard = array(
1758 array(
1759 'id' => 'iframe_standard',
1760 'name' => esc_html__( 'Embed URL', 'classifieds' ),
1761 'type' => 'text',
1762 'desc' => esc_html__( 'Input custom URL which will be embeded as the blog post media.', 'classifieds' )
1763 ),
1764 );
1765
1766 $meta_boxes[] = array(
1767 'title' => esc_html__( 'Standard Post Information', 'classifieds' ),
1768 'pages' => 'post',
1769 'fields' => $post_meta_standard,
1770 );
1771
1772 $post_meta_gallery = array(
1773 array(
1774 'id' => 'gallery_images',
1775 'name' => esc_html__( 'Gallery Images', 'classifieds' ),
1776 'type' => 'image',
1777 'repeatable' => 1,
1778 'desc' => esc_html__( 'Add images for the gallery post format. Drag and drop to change their order.', 'classifieds' )
1779 )
1780 );
1781
1782 $meta_boxes[] = array(
1783 'title' => esc_html__( 'Gallery Post Information', 'classifieds' ),
1784 'pages' => 'post',
1785 'fields' => $post_meta_gallery,
1786 );
1787
1788
1789 $post_meta_audio = array(
1790 array(
1791 'id' => 'iframe_audio',
1792 'name' => esc_html__( 'Audio URL', 'classifieds' ),
1793 'type' => 'text',
1794 'desc' => esc_html__( 'Input url to the audio source which will be media for the audio post format.', 'classifieds' )
1795 ),
1796
1797 array(
1798 'id' => 'audio_type',
1799 'name' => esc_html__( 'Audio Type', 'classifieds' ),
1800 'type' => 'select',
1801 'options' => array(
1802 'embed' => esc_html__( 'Embed', 'classifieds' ),
1803 'direct' => esc_html__( 'Direct Link', 'classifieds' )
1804 ),
1805 'desc' => esc_html__( 'Select format of the audio URL ( Direct Link - for mp3, Embed - for the links from SoundCloud, MixCloud,... ).', 'classifieds' )
1806 ),
1807 );
1808
1809 $meta_boxes[] = array(
1810 'title' => esc_html__( 'Audio Post Information', 'classifieds' ),
1811 'pages' => 'post',
1812 'fields' => $post_meta_audio,
1813 );
1814
1815 $post_meta_video = array(
1816 array(
1817 'id' => 'video',
1818 'name' => esc_html__( 'Video URL', 'classifieds' ),
1819 'type' => 'text',
1820 'desc' => esc_html__( 'Input url to the video source which will be media for the audio post format.', 'classifieds' )
1821 ),
1822 array(
1823 'id' => 'video_type',
1824 'name' => esc_html__( 'Video Type', 'classifieds' ),
1825 'type' => 'select',
1826 'options' => array(
1827 'remote' => esc_html__( 'Embed', 'classifieds' ),
1828 'self' => esc_html__( 'Direct Link', 'classifieds' ),
1829 ),
1830 'desc' => esc_html__( 'Select format of the video URL ( Direct Link - for ogg, mp4..., Embed - for the links from YouTube, Vimeo,... ).', 'classifieds' )
1831 ),
1832 );
1833
1834 $meta_boxes[] = array(
1835 'title' => esc_html__( 'Video Post Information', 'classifieds' ),
1836 'pages' => 'post',
1837 'fields' => $post_meta_video,
1838 );
1839
1840 $post_meta_quote = array(
1841 array(
1842 'id' => 'blockquote',
1843 'name' => esc_html__( 'Input Quotation', 'classifieds' ),
1844 'type' => 'textarea',
1845 'desc' => esc_html__( 'Input quote as blog media for the quote post format.', 'classifieds' )
1846 ),
1847 array(
1848 'id' => 'cite',
1849 'name' => esc_html__( 'Input Quoted Person\'s Name', 'classifieds' ),
1850 'type' => 'text',
1851 'desc' => esc_html__( 'Input quoted person\'s name for the quote post format.', 'classifieds' )
1852 ),
1853 );
1854
1855 $meta_boxes[] = array(
1856 'title' => esc_html__( 'Quote Post Information', 'classifieds' ),
1857 'pages' => 'post',
1858 'fields' => $post_meta_quote,
1859 );
1860
1861 $post_meta_link = array(
1862 array(
1863 'id' => 'link',
1864 'name' => esc_html__( 'Input Link', 'classifieds' ),
1865 'type' => 'text',
1866 'desc' => esc_html__( 'Input link as blog media for the link post format.', 'classifieds' )
1867 ),
1868 );
1869
1870 $meta_boxes[] = array(
1871 'title' => esc_html__( 'Link Post Information', 'classifieds' ),
1872 'pages' => 'post',
1873 'fields' => $post_meta_link,
1874 );
1875
1876 $clients_meta = array(
1877 array(
1878 'id' => 'client_link',
1879 'name' => esc_html__( 'Input Client Link', 'classifieds' ),
1880 'type' => 'text',
1881 'desc' => esc_html__( 'Input link to the clients website.', 'classifieds' )
1882 ),
1883 );
1884
1885 $meta_boxes[] = array(
1886 'title' => esc_html__( 'Link Information', 'classifieds' ),
1887 'pages' => 'client',
1888 'fields' => $clients_meta,
1889 );
1890
1891 $custom_field_meta = array(
1892 array(
1893 'id' => 'fields_for',
1894 'name' => esc_html__( 'Fields For', 'classifieds' ),
1895 'type' => 'taxonomy_checkboxes',
1896 'taxonomy' => 'ad-category',
1897 'desc' => esc_html__( 'Select category for which fields are.', 'classifieds' )
1898 ),
1899 );
1900
1901 $meta_boxes[] = array(
1902 'title' => esc_html__( 'Fields Information', 'classifieds' ),
1903 'pages' => 'custom_field',
1904 'fields' => $custom_field_meta,
1905 );
1906
1907 $ad_field_meta = array(
1908 array(
1909 'id' => 'ad_expire',
1910 'name' => esc_html__( 'Ad Expire Time', 'classifieds' ),
1911 'type' => 'datetime_unix',
1912 'desc' => esc_html__( 'This field is auto populated on submit and renew.', 'classifieds' )
1913 ),
1914 array(
1915 'id' => 'ad_price',
1916 'name' => esc_html__( 'Ad Price', 'classifieds' ),
1917 'type' => 'text',
1918 'desc' => esc_html__( 'Input ad price.', 'classifieds' )
1919 ),
1920 array(
1921 'id' => 'ad_discounted_price',
1922 'name' => esc_html__( 'Discounted Ad Price', 'classifieds' ),
1923 'type' => 'text',
1924 'desc' => esc_html__( 'Input dicounted ad price.', 'classifieds' )
1925 ),
1926 array(
1927 'id' => 'ad_call_for_price',
1928 'name' => esc_html__( 'Call For Info', 'classifieds' ),
1929 'type' => 'checkbox',
1930 ),
1931 array(
1932 'id' => 'ad_gmap',
1933 'name' => esc_html__( 'Ad Location', 'classifieds' ),
1934 'type' => 'gmap',
1935 'desc' => esc_html__( 'Set ad marker.', 'classifieds' )
1936 ),
1937 array(
1938 'id' => 'ad_videos',
1939 'name' => esc_html__( 'Ad Videos', 'classifieds' ),
1940 'type' => 'text',
1941 'repeatable' => 1,
1942 'desc' => esc_html__( 'Input links to ad videos.', 'classifieds' )
1943 ),
1944 array(
1945 'id' => 'ad_images',
1946 'name' => esc_html__( 'Ad Images', 'classifieds' ),
1947 'type' => 'image',
1948 'repeatable' => 1,
1949 'desc' => esc_html__( 'Input ad images.', 'classifieds' )
1950 ),
1951 array(
1952 'id' => 'ad_display_map',
1953 'name' => esc_html__( 'Ad Display Map?', 'classifieds' ),
1954 'type' => 'select',
1955 'options' => array(
1956 'yes' => esc_html__( 'Yes', 'classifieds' ),
1957 'no' => esc_html__( 'No', 'classifieds' ),
1958 ),
1959 'desc' => esc_html__( 'Enable or disable display of the map on the single page.', 'classifieds' )
1960 ),
1961 array(
1962 'id' => 'ad_featured',
1963 'name' => esc_html__( 'Ad Is Featured?', 'classifieds' ),
1964 'type' => 'select',
1965 'options' => array(
1966 'no' => esc_html__( 'No', 'classifieds' ),
1967 'yes' => esc_html__( 'Yes', 'classifieds' ),
1968 ),
1969 'desc' => esc_html__( 'Is ad featured?', 'classifieds' )
1970 ),
1971 array(
1972 'id' => 'ad_phone',
1973 'name' => esc_html__( 'Ad Phone', 'classifieds' ),
1974 'type' => 'text',
1975 'desc' => esc_html__( 'Custom phone used only for this ad.', 'classifieds' ),
1976 'default' => ''
1977 ),
1978 array(
1979 'id' => 'ad_views',
1980 'name' => esc_html__( 'Ad Views', 'classifieds' ),
1981 'type' => 'text',
1982 'desc' => esc_html__( 'Number of views of ad single page ( this field is auto incrementd ).', 'classifieds' )
1983 ),
1984 array(
1985 'id' => 'ad_paid',
1986 'name' => esc_html__( 'Ad Paid', 'classifieds' ),
1987 'type' => 'select',
1988 'options' => array(
1989 'yes' => esc_html__( 'Yes', 'classifieds' ),
1990 'no' => esc_html__( 'No', 'classifieds' ),
1991 ),
1992 'desc' => esc_html__( 'Is this ad paid for?', 'classifieds' ),
1993 'default' => 'no'
1994 ),
1995 array(
1996 'id' => 'ad_visibility',
1997 'name' => esc_html__( 'Ad Visibility', 'classifieds' ),
1998 'type' => 'select',
1999 'options' => array(
2000 'yes' => esc_html__( 'Visible', 'classifieds' ),
2001 'no' => esc_html__( 'Hidden', 'classifieds' ),
2002 ),
2003 'desc' => esc_html__( 'Visibility of the ad.', 'classifieds' ),
2004 'default' => 'yes'
2005 ),
2006 );
2007
2008 $meta_boxes[] = array(
2009 'title' => esc_html__( 'Ad Information', 'classifieds' ),
2010 'pages' => 'ad',
2011 'fields' => $ad_field_meta,
2012 );
2013
2014 return $meta_boxes;
2015}
2016
2017add_filter('sm_meta_boxes', 'classifieds_custom_meta_boxes');
2018}
2019
2020/*
2021Transform HEX to RGB color
2022*/
2023function classifieds_hex2rgb( $hex ) {
2024 $hex = str_replace("#", "", $hex);
2025
2026 $r = hexdec(substr($hex,0,2));
2027 $g = hexdec(substr($hex,2,2));
2028 $b = hexdec(substr($hex,4,2));
2029 return $r.", ".$g.", ".$b;
2030}
2031
2032
2033
2034/* custom walker class to create main top and bottom navigation */
2035class classifieds_walker extends Walker_Nav_Menu {
2036
2037 /**
2038 * @see Walker::start_lvl()
2039 * @since 3.0.0
2040 *
2041 * @param string $output Passed by reference. Used to append additional content.
2042 * @param int $depth Depth of page. Used for padding.
2043 */
2044 public function start_lvl( &$output, $depth = 0, $args = array() ) {
2045 $indent = str_repeat( "\t", $depth );
2046 $output .= "\n$indent<ul role=\"menu\" class=\" dropdown-menu\">\n";
2047 }
2048
2049 /**
2050 * @see Walker::start_el()
2051 * @since 3.0.0
2052 *
2053 * @param string $output Passed by reference. Used to append additional content.
2054 * @param object $item Menu item data object.
2055 * @param int $depth Depth of menu item. Used for padding.
2056 * @param int $current_page Menu item ID.
2057 * @param object $args
2058 */
2059 public function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {
2060 $indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';
2061
2062 /**
2063 * Dividers, Headers or Disabled
2064 * =============================
2065 * Determine whether the item is a Divider, Header, Disabled or regular
2066 * menu item. To prevent errors we use the strcasecmp() function to so a
2067 * comparison that is not case sensitive. The strcasecmp() function returns
2068 * a 0 if the strings are equal.
2069 */
2070 if ( strcasecmp( $item->attr_title, 'divider' ) == 0 && $depth === 1 ) {
2071 $output .= $indent . '<li role="presentation" class="divider">';
2072 }
2073 else if ( strcasecmp( $item->title, 'divider') == 0 && $depth === 1 ) {
2074 $output .= $indent . '<li role="presentation" class="divider">';
2075 }
2076 else if ( strcasecmp( $item->attr_title, 'dropdown-header') == 0 && $depth === 1 ) {
2077 $output .= $indent . '<li role="presentation" class="dropdown-header">' . esc_attr__( $item->title );
2078 }
2079 else if ( strcasecmp($item->attr_title, 'disabled' ) == 0 ) {
2080 $output .= $indent . '<li role="presentation" class="disabled"><a href="#">' . esc_attr__( $item->title ) . '</a>';
2081 }
2082 else {
2083
2084 $mega_menu_custom = get_post_meta( $item->ID, 'mega-menu-set', true );
2085
2086 $class_names = $value = '';
2087 $classes = empty( $item->classes ) ? array() : (array) $item->classes;
2088 if( !empty( $mega_menu_custom ) ){
2089 $classes[] = 'mega_menu_li';
2090 }
2091 $classes[] = 'menu-item-' . $item->ID;
2092 $class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item, $args ) );
2093
2094 if ( $args->has_children ){
2095 $class_names .= ' dropdown';
2096 }
2097
2098 $class_names = $class_names ? ' class="' . esc_attr__( $class_names ) . '"' : '';
2099 $id = apply_filters( 'nav_menu_item_id', 'menu-item-'. $item->ID, $item, $args );
2100 $id = $id ? ' id="' . esc_attr__( $id ) . '"' : '';
2101
2102 $output .= $indent . '<li' . $id . $value . $class_names .'>';
2103
2104 $atts = array();
2105 $atts['title'] = ! empty( $item->attr_title ) ? $item->attr_title : '';
2106 $atts['target'] = ! empty( $item->target ) ? $item->target : '';
2107 $atts['rel'] = ! empty( $item->xfn ) ? $item->xfn : '';
2108
2109 // If item has_children add atts to a.
2110 $atts['href'] = ! empty( $item->url ) ? $item->url : '';
2111 if ( $args->has_children ) {
2112 $atts['data-toggle'] = 'dropdown';
2113 $atts['class'] = 'dropdown-toggle';
2114 $atts['data-hover'] = 'dropdown';
2115 $atts['aria-haspopup'] = 'true';
2116 }
2117
2118 $atts = apply_filters( 'nav_menu_link_attributes', $atts, $item, $args );
2119
2120 $attributes = '';
2121 foreach ( $atts as $attr => $value ) {
2122 if ( ! empty( $value ) ) {
2123 $value = ( 'href' === $attr ) ? esc_url( $value ) : esc_attr__( $value );
2124 $attributes .= ' ' . $attr . '="' . $value . '"';
2125 }
2126 }
2127
2128 $item_output = $args->before;
2129
2130 /*
2131 * Glyphicons
2132 * ===========
2133 * Since the the menu item is NOT a Divider or Header we check the see
2134 * if there is a value in the attr_title property. If the attr_title
2135 * property is NOT null we apply it as the class name for the glyphicon.
2136 */
2137
2138 $item_output .= '<a'. $attributes .'>';
2139
2140 $item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;
2141 if( !empty( $mega_menu_custom ) ){
2142 $registered_widgets = wp_get_sidebars_widgets();
2143 $count = count( $registered_widgets[$mega_menu_custom] );
2144 $item_output .= '</a>';
2145 $mega_menu_min_height = classifieds_get_option( 'mega_menu_min_height' );
2146 $style = '';
2147 if( !empty( $mega_menu_min_height ) ){
2148 $style = 'style="height: '.esc_attr__( $mega_menu_min_height ).'"';
2149 }
2150 $item_output .= '<ul class="list-unstyled mega_menu col-'.$count.'" '.$style.'>';
2151 ob_start();
2152 if( is_active_sidebar( $mega_menu_custom ) ){
2153 dynamic_sidebar( $mega_menu_custom );
2154 }
2155 $item_output .= ob_get_contents();
2156 ob_end_clean();
2157 $item_output .= '</ul>';
2158 }
2159 else{
2160 $item_output .= '</a>';
2161 }
2162 $item_output .= $args->after;
2163
2164 $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
2165 }
2166 }
2167
2168 /**
2169 * Traverse elements to create list from elements.
2170 *
2171 * Display one element if the element doesn't have any children otherwise,
2172 * display the element and its children. Will only traverse up to the max
2173 * depth and no ignore elements under that depth.
2174 *
2175 * This method shouldn't be called directly, use the walk() method instead.
2176 *
2177 * @see Walker::start_el()
2178 * @since 2.5.0
2179 *
2180 * @param object $element Data object
2181 * @param array $children_elements List of elements to continue traversing.
2182 * @param int $max_depth Max depth to traverse.
2183 * @param int $depth Depth of current element.
2184 * @param array $args
2185 * @param string $output Passed by reference. Used to append additional content.
2186 * @return null Null on failure with no changes to parameters.
2187 */
2188 public function display_element( $element, &$children_elements, $max_depth, $depth, $args, &$output ) {
2189 if ( ! $element )
2190 return;
2191
2192 $id_field = $this->db_fields['id'];
2193
2194 // Display this element.
2195 if ( is_object( $args[0] ) ){
2196 $args[0]->has_children = ! empty( $children_elements[ $element->$id_field ] );
2197 }
2198
2199 parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output );
2200 }
2201
2202 /**
2203 * Menu Fallback
2204 * =============
2205 * If this function is assigned to the wp_nav_menu's fallback_cb variable
2206 * and a manu has not been assigned to the theme location in the WordPress
2207 * menu manager the function with display nothing to a non-logged in user,
2208 * and will add a link to the WordPress menu manager if logged in as an admin.
2209 *
2210 * @param array $args passed from the wp_nav_menu function.
2211 *
2212 */
2213 public static function fallback( $args ) {
2214 if ( current_user_can( 'manage_options' ) ) {
2215
2216 extract( $args );
2217
2218 $fb_output = null;
2219
2220 if ( $container ) {
2221 $fb_output = '<' . $container;
2222
2223 if ( $container_id ){
2224 $fb_output .= ' id="' . $container_id . '"';
2225 }
2226
2227 if ( $container_class ){
2228 $fb_output .= ' class="' . $container_class . '"';
2229 }
2230
2231 $fb_output .= '>';
2232 }
2233
2234 $fb_output .= '<ul';
2235
2236 if ( $menu_id ){
2237 $fb_output .= ' id="' . $menu_id . '"';
2238 }
2239
2240 if ( $menu_class ){
2241 $fb_output .= ' class="' . $menu_class . '"';
2242 }
2243
2244 $fb_output .= '>';
2245 $fb_output .= '<li><a href="' . admin_url( 'nav-menus.php' ) . '">Add a menu</a></li>';
2246 $fb_output .= '</ul>';
2247
2248 if ( $container ){
2249 $fb_output .= '</' . $container . '>';
2250 }
2251
2252 echo $fb_output;
2253 }
2254 }
2255}
2256
2257/*
2258Set sizes for cloud widget
2259*/
2260function classifieds_custom_tag_cloud_widget($args) {
2261 $args['largest'] = 18; //largest tag
2262 $args['smallest'] = 10; //smallest tag
2263 $args['unit'] = 'px'; //tag font unit
2264 return $args;
2265}
2266add_filter( 'widget_tag_cloud_args', 'classifieds_custom_tag_cloud_widget' );
2267
2268/*
2269Format wp_link_pages so it has the right css applied to it
2270*/
2271function classifieds_link_pages(){
2272 $post_pages = wp_link_pages(
2273 array(
2274 'before' => '',
2275 'after' => '',
2276 'link_before' => '<span>',
2277 'link_after' => '</span>',
2278 'next_or_number' => 'number',
2279 'nextpagelink' => esc_html__( '»', 'classifieds' ),
2280 'previouspagelink' => esc_html__( '«', 'classifieds' ),
2281 'separator' => ' ',
2282 'echo' => 0
2283 )
2284 );
2285 /* format pages that are not current ones */
2286 $post_pages = str_replace( '<a', '<li><a', $post_pages );
2287 $post_pages = str_replace( '</span></a>', '</a></li>', $post_pages );
2288 $post_pages = str_replace( '><span>', '>', $post_pages );
2289
2290 /* format current page */
2291 $post_pages = str_replace( '<span>', '<li class="active"><a href="javascript:;">', $post_pages );
2292 $post_pages = str_replace( '</span>', '</a></li>', $post_pages );
2293
2294 return $post_pages;
2295}
2296
2297/*
2298Create tags list
2299*/
2300function classifieds_tags_list(){
2301 $tags = get_the_tags();
2302 $tag_list = array();
2303 if( !empty( $tags ) ){
2304 foreach( $tags as $tag ){
2305 $tag_list[] = '<a href="'.esc_url( get_tag_link( $tag->term_id ) ).'">'.$tag->name.'</a>';
2306 }
2307 }
2308 return join( ', ', $tag_list );
2309}
2310
2311
2312/*
2313Create categories list
2314*/
2315function classifieds_categories_list(){
2316 $category_list = get_the_category();
2317 $categories = array();
2318 if( !empty( $category_list ) ){
2319 foreach( $category_list as $category ){
2320 $categories[] = '<a href="'.esc_url( get_category_link( $category->term_id ) ).'">'.$category->name.'</a>';
2321 }
2322 }
2323
2324 return join( ', ', $categories );
2325}
2326
2327/*
2328Format pagination so it has correct style applied to it
2329*/
2330function classifieds_format_pagination( $page_links ){
2331 global $classifieds_slugs;
2332 $list = '';
2333 if( !empty( $page_links ) ){
2334 foreach( $page_links as $page_link ){
2335 if( strpos( $page_link, 'page-numbers current' ) !== false ){
2336 $page_link = str_replace( "<span class='page-numbers current'>", '<a href="javascript:;">', $page_link );
2337 $page_link = str_replace( '</span>', '</a>', $page_link );
2338 $list .= '<li class="active">'.$page_link.'</li>';
2339 }
2340 else{
2341 $list .= '<li>'.$page_link.'</li>';
2342 }
2343
2344 }
2345 }
2346
2347 return $list;
2348}
2349
2350/*
2351Generate random string
2352*/
2353function classifieds_random_string( $length = 10 ) {
2354 $characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
2355 $random = '';
2356 for ($i = 0; $i < $length; $i++) {
2357 $random .= $characters[rand(0, strlen($characters) - 1)];
2358 }
2359 return $random;
2360}
2361
2362
2363/*
2364Add the ... at the end of the excerpt
2365*/
2366function classifieds_new_excerpt_more( $more ) {
2367 return '';
2368}
2369add_filter('excerpt_more', 'classifieds_new_excerpt_more');
2370
2371/*
2372Create options for the select box in the category icon select
2373*/
2374function classifieds_icons_list( $value ){
2375 $icons_list = classifieds_awesome_icons_list();
2376
2377 $select_data = '';
2378
2379 foreach( $icons_list as $key => $label){
2380 $select_data .= '<option value="'.esc_attr__( $key ).'" '.( $value == $key ? 'selected="selected"' : '' ).'>'.$label.'</option>';
2381 }
2382
2383 return $select_data;
2384}
2385
2386/*
2387Submit contact form
2388*/
2389function classifieds_send_contact(){
2390 $errors = array();
2391 $name = isset( $_POST['name'] ) ? esc_sql( $_POST['name'] ) : '';
2392 $email = isset( $_POST['email'] ) ? esc_sql( $_POST['email'] ) : '';
2393 $message = isset( $_POST['message'] ) ? esc_sql( $_POST['message'] ) : '';
2394 if( isset( $_POST['captcha'] ) ){
2395 if( !empty( $name ) && !empty( $email ) && !empty( $message ) ){
2396 if( filter_var( $email, FILTER_VALIDATE_EMAIL ) ){
2397 $email_to = classifieds_get_option( 'contact_mail' );
2398 $subject = classifieds_get_option( 'contact_form_subject' );
2399 if( !empty( $email_to ) ){
2400 $message = "
2401 ".esc_html__( 'Name: ', 'classifieds' )." {$name} \n
2402 ".esc_html__( 'Email: ', 'classifieds' )." {$email} \n
2403 ".esc_html__( 'Message: ', 'classifieds' )."\n {$message} \n
2404 ";
2405 $info = @wp_mail( $email_to, $subject, $message );
2406 if( $info ){
2407 $message = '<div class="alert alert-danger">'.esc_html__( 'Your message was successfully submitted.', 'classifieds' ).'</div>';
2408 }
2409 else{
2410 $message = '<div class="alert alert-danger">'.esc_html__( 'Unexpected error while attempting to send e-mail.', 'classifieds' ).'</div>';
2411 }
2412 }
2413 else{
2414 $message = '<div class="alert alert-danger">'.esc_html__( 'Message is not send since the recepient email is not yet set.', 'classifieds' ).'</div>';
2415 }
2416 }
2417 else{
2418 $message = '<div class="alert alert-danger">'.esc_html__( 'Email is not valid.', 'classifieds' ).'</div>';
2419 }
2420 }
2421 else{
2422 $message = '<div class="alert alert-danger">'.esc_html__( 'All fields are required.', 'classifieds' ).'</div>';
2423 }
2424 }
2425 else{
2426 $message = '<div class="alert alert-danger">'.esc_html__( 'Captcha is wrong.', 'classifieds' ).'</div>';
2427 }
2428
2429 echo json_encode(array(
2430 'message' => $message
2431 ));
2432 die();
2433}
2434add_action('wp_ajax_contact', 'classifieds_send_contact');
2435add_action('wp_ajax_nopriv_contact', 'classifieds_send_contact');
2436
2437
2438/*
2439Send subscription values to mailchimp
2440*/
2441function classifieds_send_subscription(){
2442 if( isset( $_POST['captcha'] ) ){
2443 $email = !empty( $_POST["email"] ) ? $_POST["email"] : '';
2444 $response = array();
2445 if( filter_var( $email, FILTER_VALIDATE_EMAIL ) ){
2446 require_once( classifieds_load_path( 'includes/mailchimp.php' ) );
2447 $chimp_api = classifieds_get_option("mail_chimp_api");
2448 $chimp_list_id = classifieds_get_option("mail_chimp_list_id");
2449 if( !empty( $chimp_api ) && !empty( $chimp_list_id ) ){
2450 $mc = new MailChimp( $chimp_api );
2451 $result = $mc->call('lists/subscribe', array(
2452 'id' => $chimp_list_id,
2453 'email' => array( 'email' => $email )
2454 ));
2455
2456 if( $result === false) {
2457 $message = '<div class="alert alert-danger">'.esc_html__( 'There was an error contacting the API, please try again.', 'classifieds' ).'</div>';
2458 }
2459 else if( isset($result['status']) && $result['status'] == 'error' ){
2460 $message = '<div class="alert alert-danger">'.json_encode($result).'</div>';
2461 }
2462 else{
2463 $message = '<div class="alert alert-success">'.esc_html__( 'You have successfully subscribed to the newsletter.', 'classifieds' ).'</div>';
2464 }
2465
2466 }
2467 else{
2468 $message = '<div class="alert alert-danger">'.esc_html__( 'API data are not yet set.', 'classifieds' ).'</div>';
2469 }
2470 }
2471 else{
2472 $message = '<div class="alert alert-danger">'.esc_html__( 'Email is empty or invalid.', 'classifieds' ).'</div>';
2473 }
2474 }
2475 echo json_encode( array(
2476 'message' => $message
2477 ) );
2478 die();
2479}
2480add_action('wp_ajax_subscribe', 'classifieds_send_subscription');
2481add_action('wp_ajax_nopriv_subscribe', 'classifieds_send_subscription');
2482
2483/*
2484Extract avatar url from the img tag
2485*/
2486function classifieds_get_avatar_url( $get_avatar ){
2487 preg_match("/src='(.*?)'/i", $get_avatar, $matches);
2488 if( empty( $matches[1] ) ){
2489 preg_match("/src=\"(.*?)\"/i", $get_avatar, $matches);
2490 }
2491 return $matches[1];
2492}
2493
2494/*
2495Add video container arround embeded videos
2496*/
2497function classifieds_embed_html( $html ) {
2498 return '<div class="video-container">' . $html . '</div>';
2499}
2500add_filter( 'embed_oembed_html', 'classifieds_embed_html', 10, 3 );
2501add_filter( 'video_embed_html', 'classifieds_embed_html' ); // Jetpack
2502
2503/*
2504List comments
2505*/
2506function classifieds_comments( $comment, $args, $depth ) {
2507 $GLOBALS['comment'] = $comment;
2508 $add_below = '';
2509 ?>
2510 <!-- comment-1 -->
2511 <div class="media <?php echo $depth > 1 ? esc_attr__( 'left-padding' ) : ''; ?>">
2512 <div class="comment-inner">
2513 <?php
2514 $avatar = classifieds_get_avatar_url( get_avatar( $comment, 90 ) );
2515 if( !empty( $avatar ) ): ?>
2516 <a class="pull-left" href="javascript:;">
2517 <img src="<?php echo esc_url( $avatar ); ?>" class="media-object comment-avatar" title="" alt="">
2518 </a>
2519 <?php endif; ?>
2520 <div class="media-body comment-body">
2521 <div class="pull-left">
2522 <h4><?php comment_author(); ?></h4>
2523 <span><?php echo human_time_diff( get_the_time('U'), current_time('timestamp') ) . esc_html__( ' ago', 'classifieds' ); ?></span>
2524 </div>
2525 <div class="pull-right">
2526 <?php
2527 comment_reply_link(
2528 array_merge(
2529 $args,
2530 array(
2531 'reply_text' => esc_html__( 'REPLY', 'classifieds' ),
2532 'add_below' => $add_below,
2533 'depth' => $depth,
2534 'max_depth' => $args['max_depth']
2535 )
2536 )
2537 );
2538 ?>
2539 </div>
2540 <div class="clearfix"></div>
2541 <?php
2542 if ($comment->comment_approved != '0'){
2543 ?>
2544 <p><?php echo get_comment_text(); ?></p>
2545 <?php
2546 }
2547 else{ ?>
2548 <p><?php esc_html_e('Your comment is awaiting moderation.', 'classifieds'); ?></p>
2549 <?php
2550 }
2551 ?>
2552 </div>
2553 </div>
2554 </div>
2555 <!-- .comment-1 -->
2556 <?php
2557}
2558
2559/*
2560Remove ending div on comments
2561*/
2562function classifieds_end_comments(){
2563 return "";
2564}
2565
2566/*
2567Check if blog has media
2568*/
2569function classifieds_has_media(){
2570 $post_format = get_post_format();
2571 switch( $post_format ){
2572 case 'aside' :
2573 return has_post_thumbnail() ? true : false; break;
2574
2575 case 'audio' :
2576 $iframe_audio = get_post_meta( get_the_ID(), 'iframe_audio', true );
2577 if( !empty( $iframe_audio ) ){
2578 return true;
2579 }
2580 else if( has_post_thumbnail() ){
2581 return true;
2582 }
2583 else{
2584 return false;
2585 }
2586 break;
2587
2588 case 'chat' :
2589 return has_post_thumbnail() ? true : false; break;
2590
2591 case 'gallery' :
2592 $post_meta = get_post_custom();
2593 $gallery_images = classifieds_smeta_images( 'gallery_images', get_the_ID(), array() );
2594 if( !empty( $gallery_images ) ){
2595 return true;
2596 }
2597 else if( has_post_thumbnail() ){
2598 return true;
2599 }
2600 else{
2601 return false;
2602 }
2603 break;
2604
2605 case 'image':
2606 return has_post_thumbnail() ? true : false; break;
2607
2608 case 'link' :
2609 $link = get_post_meta( get_the_ID(), 'link', true );
2610 if( !empty( $link ) ){
2611 return true;
2612 }
2613 else{
2614 return false;
2615 }
2616 break;
2617
2618 case 'quote' :
2619 $blockquote = get_post_meta( get_the_ID(), 'blockquote', true );
2620 $cite = get_post_meta( get_the_ID(), 'cite', true );
2621 if( !empty( $blockquote ) || !empty( $cite ) ){
2622 return true;
2623 }
2624 else if( has_post_thumbnail() ){
2625 return true;
2626 }
2627 else{
2628 return false;
2629 }
2630 break;
2631
2632 case 'status' :
2633 return has_post_thumbnail() ? true : false; break;
2634
2635 case 'video' :
2636 $video = get_post_meta( get_the_ID(), 'video', true );
2637 if( !empty( $video ) ){
2638 return true;
2639 }
2640 else if( has_post_thumbnail() ){
2641 return true;
2642 }
2643 else{
2644 return false;
2645 }
2646 break;
2647
2648 default:
2649 $iframe_standard = get_post_meta( get_the_ID(), 'iframe_standard', true );
2650 if( !empty( $iframe_standard ) ){
2651 return true;
2652 }
2653 else if( has_post_thumbnail() ){
2654 return true;
2655 }
2656 else{
2657 return false;
2658 }
2659 break;
2660 }
2661}
2662
2663/*
2664Format price
2665*/
2666if( !function_exists('classifieds_format_price_number') ){
2667 function classifieds_format_price_number( $price ){
2668 if( !is_numeric( $price ) ){
2669 return $price;
2670 }
2671 $unit_position = classifieds_get_option( 'unit_position' );
2672 $unit = classifieds_get_option( 'unit' );
2673
2674 if( $unit_position == 'front' ){
2675 return $unit.number_format( $price, 2 );
2676 }
2677 else{
2678 return number_format( $price, 2 ).$unit;
2679 }
2680 }
2681}
2682
2683/*
2684Get price HTMl for the ad
2685*/
2686function classifieds_get_price( $post_id ){
2687 $ad_price = get_post_meta( $post_id, 'ad_price', true );
2688 $ad_call_for_price = get_post_meta( $post_id, 'ad_call_for_price', true );
2689 $ad_discounted_price = get_post_meta( $post_id, 'ad_discounted_price', true );
2690
2691 if( $ad_call_for_price == '1' ){
2692 echo '<span class="call-price">'.esc_html__( 'Call For Info', 'classifieds' ).'</span>';
2693 }
2694 else if( empty( $ad_price ) ){
2695 echo '<span class="free-price">'.esc_html__( 'Free', 'classifieds' ).'</span>';
2696 }
2697 else{
2698 if( !empty( $ad_price ) ){
2699 $ad_price = classifieds_format_price_number( $ad_price );
2700 }
2701
2702 if( !empty( $ad_discounted_price ) ){
2703 $ad_discounted_price = classifieds_format_price_number( $ad_discounted_price );
2704 echo $ad_discounted_price;
2705 ?>
2706 <span><?php echo $ad_price; ?></span>
2707 <?php
2708 }
2709 else{
2710 echo $ad_price;
2711 }
2712 }
2713}
2714
2715/*
2716Get prcing shortcode boxes
2717*/
2718function classifieds_pricing_format( $price ){
2719 $price = number_format( $price, 2 );
2720 $unit_position = classifieds_get_option( 'unit_position' );
2721 $unit = classifieds_get_option( 'unit' );
2722 $price_el = explode('.', $price);
2723 $main_price = $price_el[0];
2724 $decimal_price = $price_el[1];
2725 if( $unit_position == 'back' ){
2726 $price_html = $main_price.'<span>.'.$decimal_price.'</span><span>'.$unit.'</span>';
2727 }
2728 else{
2729 $price_html = '<span>'.$unit.'</span>'.$main_price.'<span>.'.$decimal_price.'</span>';
2730 }
2731
2732 return $price_html;
2733}
2734
2735/*
2736Custom login messages
2737*/
2738function classifieds_login_errors( $message ) {
2739 global $errors;
2740 if( isset( $errors->errors['invalid_username'] ) ){
2741 $message = esc_html__( 'Invalid username', 'classifieds' );
2742 }
2743 else if ( isset( $errors->errors['incorrect_password'] ) ){
2744 $message = esc_html__( 'Invalid password', 'classifieds' );
2745 }
2746
2747 return $message;
2748}
2749add_filter( 'login_errors', 'classifieds_login_errors' );
2750
2751/*
2752Parse video URLs
2753*/
2754function classifieds_parse_url( $url ){
2755 if( stripos( $url, 'youtube' ) ){
2756 $temp = explode( '?v=', $url );
2757 return 'https://www.youtube.com/embed/'.$temp[1];
2758 }
2759 else if( stripos( $url, 'vimeo' ) ){
2760 $temp = explode( 'vimeo.com/', $url );
2761 return '//player.vimeo.com/video/'.$temp[sizeof( $temp ) - 1];
2762 }
2763 else{
2764 return $url;
2765 }
2766}
2767
2768/*
2769Create breadcrumbs
2770*/
2771function classifieds_get_breadcrumbs(){
2772 global $offer_type, $offer_cat, $location, $classifieds_slugs;
2773 $breadcrumb = '';
2774 if( function_exists( 'is_woocommerce' ) && is_woocommerce() ){
2775 return false;
2776 }
2777 if( is_front_page() ){
2778 return '';
2779 }
2780 $breadcrumb .= '<ul class="breadcrumb">';
2781 if( is_home() ){
2782 $breadcrumb .= '<li><a href="'.home_url().'">'.esc_html__( 'Home', 'classifieds' ).'</a></li><li>'.esc_html__( 'Blog', 'classifieds' ).'</li>';
2783 }
2784 else{
2785 $blog_page = get_option( 'page_for_posts' );
2786 $blog_url = get_permalink( $blog_page );
2787 if( !is_home() ){
2788 $breadcrumb .= '<li><a href="'.home_url().'">'.esc_html__( 'Home', 'classifieds' ).'</a></li>';
2789 }
2790 if( is_category() ){
2791 $breadcrumb .= '<li><a href="'.esc_url( $blog_url ).'">'.esc_html__( 'Blog', 'classifieds' ).'</a></li>';
2792 $breadcrumb .= '<li>'.single_cat_title( '', false ).'</li>';
2793 }
2794 else if( is_404() ){
2795 $breadcrumb .= '<li>'.esc_html__( '404 Page Doesn\'t exists', 'classifieds' ).'</li>';
2796 }
2797 else if( is_tag() ){
2798 $breadcrumb .= '<li><a href="'.esc_url( $blog_url ).'">'.esc_html__( 'Blog', 'classifieds' ).'</a></li>';
2799 $breadcrumb .= '<li>'.esc_html__('Search by tag: ', 'classifieds'). get_query_var('tag').'</li>';
2800 }
2801 else if( is_author() ){
2802 $breadcrumb .= '<li><a href="'.esc_url( $blog_url ).'">'.esc_html__( 'Blog', 'classifieds' ).'</a></li>';
2803 $breadcrumb .= '<li>'.esc_html__('Posts by ', 'classifieds').''.get_the_author_meta( 'display_name' ).'</li>';
2804 }
2805 else if( is_archive() ){
2806 $breadcrumb .= '<li><a href="'.esc_url( $blog_url ).'">'.esc_html__( 'Blog', 'classifieds' ).'</a></li>';
2807 $breadcrumb .= '<li>'.esc_html__('Archive for:', 'classifieds'). single_month_title( ' ', false ).'</li>';
2808 }
2809 else if( is_search() ){
2810 $breadcrumb .= '<li><a href="'.esc_url( $blog_url ).'">'.esc_html__( 'Blog', 'classifieds' ).'</a></li>';
2811 $breadcrumb .= '<li>'.esc_html__('Results for: ', 'classifieds').' '. get_search_query().'</li>';
2812 }
2813 else{
2814 if( is_singular( 'post' ) ){
2815 $breadcrumb .= '<li><a href="'.esc_url( $blog_url ).'">'.esc_html__( 'Blog', 'classifieds' ).'</a></li>';
2816 }
2817 else if( is_singular('ad') ){
2818 $terms = get_the_terms( get_the_ID(), 'ad-category');
2819 if( !empty( $terms ) ){
2820 $terms_organized = array();
2821 classifieds_sort_terms_hierarchicaly($terms, $terms_organized);
2822 $permalink = classifieds_get_permalink_by_tpl( 'page-tpl_search_page' );
2823 if( !empty( $terms_organized ) ){
2824 $cat = array_pop( $terms_organized );
2825 $breadcrumb .= '<li><a href="'.esc_url( add_query_arg( array( $classifieds_slugs['category'] => $cat->slug ), $permalink ) ).'">'.$cat->name.'</a></li>';
2826 }
2827 }
2828 }
2829 $breadcrumb .= '<li>'.get_the_title().'</li>';
2830 }
2831 }
2832 $breadcrumb .= '</ul>';
2833
2834 return $breadcrumb;
2835}
2836
2837
2838/*
2839Filter images by author
2840*/
2841add_filter( 'ajax_query_attachments_args', 'classifieds_filter_images', 10, 1 );
2842function classifieds_filter_images($query = array()) {
2843 $has_memebers_page = classifieds_get_permalink_by_tpl( 'page-tpl_my_profile' );
2844 if( $has_memebers_page !== 'javascript:;' ){
2845 $query['author'] = get_current_user_id();
2846 }
2847 return $query;
2848}
2849
2850/*
2851Redirect non administrators
2852*/
2853add_action( 'admin_init', 'classifieds_non_admin_users' );
2854function classifieds_non_admin_users() {
2855 $user_ID = get_current_user_id();
2856 $user_agent = get_user_meta( $user_ID, 'user_agent', true );
2857 if ( ! current_user_can( 'manage_options' ) && !stristr( $_SERVER['PHP_SELF'], 'admin-ajax.php' ) && !stristr( $_SERVER['PHP_SELF'], 'async-upload.php' ) && ( !$user_agent || $user_agent == 'no' )) {
2858 wp_redirect( home_url() );
2859 exit;
2860 }
2861}
2862
2863/*
2864Append style of the shortcode
2865*/
2866function classifieds_shortcode_style( $style_css ){
2867 $style_css = str_replace( '<style', '<style scoped', $style_css );
2868 return $style_css;
2869}
2870
2871
2872/*
2873Rename permalink slugs
2874*/
2875global $classifieds_slugs;
2876$classifieds_slugs = array(
2877 'category' => 'category',
2878 'tag' => 'tag',
2879 'keyword' => 'keyword',
2880 'location' => 'location',
2881 'longitude' => 'longitude',
2882 'latitude' => 'latitude',
2883 'radius' => 'radius',
2884 'view' => 'view',
2885 'sortby' => 'sortby',
2886 'subpage' => 'subpage'
2887);
2888
2889
2890/*
2891populate slugs with translate values
2892*/
2893function classifieds_get_classifieds_slugs(){
2894 global $classifieds_slugs;
2895 foreach( $classifieds_slugs as &$slug ){
2896 $trans = classifieds_get_option( 'trans_'.$slug );
2897 if( !empty( $trans ) ){
2898 $slug = $trans;
2899 }
2900 }
2901}
2902add_action( 'init', 'classifieds_get_classifieds_slugs', 1, 0);
2903
2904
2905/* generate nicve permalink structure */
2906function classifieds_append_query_string( $permalink, $include = array(), $exclude = array( 'coupon' ) ){
2907 global $classifieds_slugs;
2908 global $wp;
2909 if ( !$permalink ){
2910 $permalink = get_permalink();
2911 }
2912
2913 // Map endpoint to options
2914 if ( get_option( 'permalink_structure' ) ) {
2915 if ( strstr( $permalink, '?' ) ) {
2916 $query_string = '?' . parse_url( $permalink, PHP_URL_QUERY );
2917 $permalink = current( explode( '?', $permalink ) );
2918 } else {
2919 $query_string = '';
2920 }
2921
2922 $permalink = trailingslashit( $permalink );
2923 if( !empty( $include ) ){
2924 foreach( $include as $arg => $value ){
2925 $permalink .= $classifieds_slugs[$arg].'/'.$value.'/';
2926 }
2927 }
2928 foreach( $classifieds_slugs as $slug => $trans_slug ){
2929 if( isset( $wp->query_vars[$trans_slug] ) && !isset( $include[$slug] ) && !in_array( $slug, $exclude ) && !in_array( 'all', $exclude ) ){
2930 $permalink .= $trans_slug.'/'.$wp->query_vars[$trans_slug].'/';
2931 }
2932 }
2933 $permalink .= $query_string;
2934 }
2935 else {
2936 if( !empty( $include ) ){
2937 foreach( $include as $arg => $value ){
2938 $permalink = esc_url( add_query_arg( array( $classifieds_slugs[$arg] => $value ), $permalink ) );
2939 }
2940 }
2941 foreach( $classifieds_slugs as $slug => $trans_slug ){
2942 if( isset( $wp->query_vars[$trans_slug] ) && !isset( $include[$slug] ) && !in_array( $slug, $exclude ) && !in_array( 'all', $exclude ) ){
2943 $permalink = esc_url( add_query_arg( array( $trans_slug => $wp->query_vars[$trans_slug] ), $permalink ) );
2944 }
2945 }
2946
2947 }
2948
2949 return $permalink;
2950}
2951
2952/*
2953Rewrite rules
2954*/
2955function classifieds_add_rewrite_rules() {
2956 global $wp_rewrite;
2957 global $classifieds_slugs;
2958 $new_rules = array();
2959 $custom_rules = array();
2960 for( $i=count( $classifieds_slugs ); $i>=1; $i-- ){
2961 $key = str_repeat( '('.join('|', $classifieds_slugs).')/(.+?)/', $i );
2962
2963 $key_1 = '([^/]*)/'.$key.'(page)/(.+?)/?$';
2964 $key_2 = '([^/]*)/'.$key.'?$';
2965 $rewrite_to = 'index.php?pagename='.$wp_rewrite->preg_index( 1 );
2966
2967 for( $k=2; $k<=($i*2)+1; $k+=2 ){
2968 $rewrite_to .= '&' . $wp_rewrite->preg_index( $k ) . '=' . $wp_rewrite->preg_index( $k+1 );
2969 }
2970
2971 $custom_rules[$key_1] = $rewrite_to.'&paged='.$wp_rewrite->preg_index( $k+1 );
2972 $custom_rules[$key_2] = $rewrite_to;
2973
2974 }
2975
2976 $wp_rewrite->rules = $custom_rules + $wp_rewrite->rules ;
2977}
2978add_action( 'generate_rewrite_rules', 'classifieds_add_rewrite_rules' );
2979
2980/*
2981Register user
2982*/
2983function classifieds_register(){
2984 $username = isset( $_POST['register-username'] ) ? esc_sql( $_POST['register-username'] ) : '';
2985 $password = isset( $_POST['register-password'] ) ? esc_sql( $_POST['register-password'] ) : '';
2986 $repeat_password = isset( $_POST['register-password-repeat'] ) ? esc_sql( $_POST['register-password-repeat'] ) : '';
2987 $email = isset( $_POST['register-email'] ) ? esc_sql( $_POST['register-email'] ) : '';
2988 $message = '';
2989
2990 if( isset( $_POST['captcha'] ) ){
2991 if( !empty( $email ) && !empty( $username ) && !empty( $password ) && !empty( $repeat_password ) ){
2992 if( filter_var($email, FILTER_VALIDATE_EMAIL) ){
2993 if( $password == $repeat_password ){
2994 if( !username_exists( $username ) ){
2995 if( !email_exists( $email ) ){
2996 $user_id = wp_insert_user(array(
2997 'user_login' => $username,
2998 'user_pass' => $password,
2999 'user_email' => $email
3000 ));
3001 if( !is_wp_error($user_id) ) {
3002 wp_update_user(array(
3003 'ID' => $user_id,
3004 'role' => 'editor'
3005 ));
3006 $confirmation_hash = classifieds_confirm_hash();
3007 update_user_meta( $user_id, 'user_active_status', 'inactive' );
3008 update_user_meta( $user_id, 'confirmation_hash', $confirmation_hash );
3009
3010 $confirmation_message = classifieds_get_option( 'registration_message' );
3011 $confirmation_link = home_url('/');
3012 $confirmation_link = add_query_arg( array( 'username' => $username, 'confirmation_hash' => $confirmation_hash ), $confirmation_link );
3013
3014 $confirmation_message = str_replace( '%LINK%', $confirmation_link, $confirmation_message );
3015
3016 $registration_subject = classifieds_get_option( 'registration_subject' );
3017
3018 $email_sender = classifieds_get_option( 'email_sender' );
3019 $name_sender = classifieds_get_option( 'name_sender' );
3020 $headers = array();
3021 $headers[] = "MIME-Version: 1.0";
3022 $headers[] = "Content-Type: text/html; charset=UTF-8";
3023 $headers[] = "From: ".$name_sender." <".$email_sender.">";
3024
3025 $info = wp_mail( $email, $registration_subject, $confirmation_message, $headers );
3026 if( $info ){
3027 $message = '<div class="alert alert-success">'.esc_html__( 'Thank you for registering, an email to confirm your email address is sent to your inbox.', 'classifieds' ).'</div>';
3028 }
3029 else{
3030 $message = '<div class="alert alert-danger">'.esc_html__( 'There was an error trying to send an email', 'classifieds' ).'</div>';
3031 }
3032 }
3033 else{
3034 $message = '<div class="alert alert-danger">'.esc_html__( 'There was an error while trying to register you', 'classifieds' ).'</div>';
3035 }
3036 }
3037 else{
3038 $message = '<div class="alert alert-danger">'.esc_html__( 'Email is already registered', 'classifieds' ).'</div>';
3039 }
3040 }
3041 else{
3042 $message = '<div class="alert alert-danger">'.esc_html__( 'Username is already registered', 'classifieds' ).'</div>';
3043 }
3044 }
3045 else{
3046 $message = '<div class="alert alert-danger">'.esc_html__( 'Provided passwords do not match', 'classifieds' ).'</div>';
3047 }
3048 }
3049 else{
3050 $message = '<div class="alert alert-danger">'.esc_html__( 'Email address is invalid', 'classifieds' ).'</div>';
3051 }
3052 }
3053 else{
3054 $message = '<div class="alert alert-danger">'.esc_html__( 'All fields are required', 'classifieds' ).'</div>';
3055 }
3056 }
3057 else{
3058 $message = '<div class="alert alert-danger">'.esc_html__( 'Captcha is wrong', 'classifieds' ).'</div>';
3059 }
3060
3061 $response = array(
3062 'message' => $message,
3063 );
3064
3065 if( !empty( $url ) ){
3066 $response['url'] = $url;
3067 }
3068
3069 echo json_encode( $response );
3070 die();
3071}
3072add_action('wp_ajax_register', 'classifieds_register');
3073add_action('wp_ajax_nopriv_register', 'classifieds_register');
3074
3075/*
3076Login user
3077*/
3078function classifieds_login(){
3079 $username = isset( $_POST['login-username'] ) ? esc_sql( $_POST['login-username'] ) : '';
3080 $password = isset( $_POST['login-password'] ) ? esc_sql( $_POST['login-password'] ) : '';
3081 $remember = isset( $_POST['login-remember'] ) ? true : false;
3082 $message = '';
3083
3084 if( isset( $_POST['captcha'] ) ){
3085 $user = get_user_by( 'login', $username );
3086 if( $user ){
3087 $is_active = get_user_meta( $user->ID, 'user_active_status', true );
3088 if( empty( $is_active ) || $is_active == 'active' ){
3089 $user = wp_signon( array(
3090 'user_login' => $username,
3091 'user_password' => $password,
3092 'remember' => isset( $_POST['remember_me'] ) ? true : false
3093 ), is_ssl() );
3094 if ( is_wp_error($user) ){
3095 switch( $user->get_error_code() ){
3096 case 'invalid_username':
3097 $message = esc_html__( 'Invalid username', 'classifieds' );
3098 break;
3099 case 'incorrect_password':
3100 $message = esc_html__( 'Invalid password', 'classifieds' );
3101 break;
3102 }
3103 $message = '<div class="alert alert-danger">'.$message.'</div>';
3104 }
3105 else{
3106 $message = '<div class="alert alert-success">'.esc_html__( 'You have been logged in.', 'classifieds' ).'</div>';
3107 if( !empty( $_POST['redirect'] ) ){
3108 $url = $_POST['redirect'];
3109 }
3110 else{
3111 $url = home_url('/');
3112 }
3113 }
3114 }
3115 else{
3116 $message = '<div class="alert alert-danger">'.esc_html__( 'Your account is not activated. Check you mail for the activation link.', 'classifieds' ).'</div>';
3117 }
3118 }
3119 else{
3120 $message = '<div class="alert alert-danger">'.esc_html__( 'Invalid username', 'classifieds' ).'</div>';
3121 }
3122 }
3123 else{
3124 $message = '<div class="alert alert-danger">'.esc_html__( 'Captcha is wrong', 'classifieds' ).'</div>';
3125 }
3126
3127 $response = array(
3128 'message' => $message,
3129 );
3130
3131 if( !empty( $url ) ){
3132 $response['url'] = $url;
3133 }
3134
3135 echo json_encode( $response );
3136 die();
3137}
3138add_action('wp_ajax_login', 'classifieds_login');
3139add_action('wp_ajax_nopriv_login', 'classifieds_login');
3140
3141
3142
3143/*
3144Recover password
3145*/
3146function classifieds_recover_password(){
3147 if( isset( $_POST['captcha'] ) ){
3148 $email = !empty( $_POST["recover-email"] ) ? $_POST["recover-email"] : '';
3149 $response = array();
3150 if( filter_var( $email, FILTER_VALIDATE_EMAIL ) ){
3151 if( email_exists( $email ) ){
3152 $lost_password_message = classifieds_get_option( 'lost_password_message' );
3153 $lost_password_subject = classifieds_get_option( 'lost_password_subject' );
3154
3155 $user = get_user_by( 'email', $email );
3156
3157 $new_password = classifieds_random_string( 5 );
3158 $update_fields = array(
3159 'ID' => $user->ID,
3160 'user_pass' => $new_password,
3161 );
3162
3163 $update_id = wp_update_user( $update_fields );
3164
3165 $lost_password_message = str_replace( '%USERNAME%', $user->user_login, $lost_password_message );
3166 $lost_password_message = str_replace( '%PASSWORD%', $new_password, $lost_password_message );
3167
3168 $registration_subject = classifieds_get_option( 'registration_subject' );
3169
3170 $email_sender = classifieds_get_option( 'email_sender' );
3171 $name_sender = classifieds_get_option( 'name_sender' );
3172 $headers = array();
3173 $headers[] = "MIME-Version: 1.0";
3174 $headers[] = "Content-Type: text/html; charset=UTF-8";
3175 $headers[] = "From: ".$name_sender." <".$email_sender.">";
3176
3177 $info = wp_mail( $email, $lost_password_subject, $lost_password_message, $headers );
3178 if( $info ){
3179 $message = '<div class="alert alert-success">'.esc_html__( 'Email with new password has been sent to your email address.', 'classifieds' ).'</div>';
3180 }
3181 else{
3182 $message = '<div class="alert alert-danger">'.esc_html__( 'There was an error trying to send an email', 'classifieds' ).'</div>';
3183 }
3184 }
3185 else{
3186 $message = '<div class="alert alert-danger">'.esc_html__( 'This email is not registered', 'classifieds' ).'</div>';
3187 }
3188 }
3189 else{
3190 $message = '<div class="alert alert-danger">'.esc_html__( 'Email is empty or invalid.', 'classifieds' ).'</div>';
3191 }
3192 }
3193 else{
3194 $message = '<div class="alert alert-danger">'.esc_html__( 'Captcha is wrong', 'classifieds' ).'</div>';
3195 }
3196 echo json_encode( array(
3197 'message' => $message
3198 ) );
3199 die();
3200}
3201add_action('wp_ajax_recover', 'classifieds_recover_password');
3202add_action('wp_ajax_nopriv_recover', 'classifieds_recover_password');
3203
3204/*
3205
3206Allow bigger SQL
3207*/
3208function classifieds_safe_sql(){
3209 global $wpdb;
3210 $wpdb->query( 'SET SESSION SQL_BIG_SELECTS=1' );
3211}
3212add_action( 'init', 'classifieds_safe_sql' );
3213
3214/*
3215Set taxonomy terms by hierarchy
3216*/
3217function classifieds_sort_terms_hierarchicaly(Array &$cats, Array &$into, $parentId = 0){
3218 foreach ($cats as $i => $cat) {
3219 if ($cat->parent == $parentId) {
3220 $into[$cat->term_id] = $cat;
3221 unset($cats[$i]);
3222 }
3223 }
3224 foreach ($into as $topCat) {
3225 $topCat->children = array();
3226 classifieds_sort_terms_hierarchicaly($cats, $topCat->children, $topCat->term_id);
3227 }
3228}
3229
3230/*
3231Create select box for the taxonomy
3232*/
3233function classifieds_get_taxonomy_select_search( $taxonomy, $selected, $field = "slug" ){
3234 $list = '';
3235 $terms = get_terms( $taxonomy, array( 'hide_empty' => false ) );
3236 $terms_organized = array();
3237 classifieds_sort_terms_hierarchicaly($terms, $terms_organized);
3238 $terms = (array) $terms_organized;
3239 $list = '';
3240 if( !empty( $terms ) ){
3241 $list = classifieds_get_taxonomy_search_tree( $terms, $selected, $field );
3242 }
3243
3244 echo $list;
3245}
3246
3247/*
3248Create radius options
3249*/
3250function classifieds_get_radius_options( $selected, $unit ){
3251 $radius_options = classifieds_get_option( 'radius_options' );
3252 $radius_options = explode( "\n", $radius_options );
3253 if( !empty( $radius_options ) ){
3254 foreach( $radius_options as $radius ){
3255 if( !empty( $radius ) ){
3256 $radius = trim( $radius );
3257 echo '<option value="'.esc_attr__( $radius ).'" '.( $radius == $selected ? 'selected="selected"' : '' ).'>'.$radius.''.$unit.'</option>';
3258 }
3259 }
3260 }
3261}
3262
3263/*
3264Get option tags for the select in the function before
3265*/
3266function classifieds_get_taxonomy_search_tree( $terms, $selected, $field, $depth = 0 ){
3267 $list = '';
3268 foreach( $terms as $term ){
3269 $list .= '<option value="'.$term->$field.'" '.( $selected == $term->$field ? 'selected="selected"' : '' ).' '.( $depth > 0 ? 'class="subitem"' : '' ).'>'.str_repeat( ' ', $depth ).' '.$term->name.'</option>';
3270 if( !empty( $term->children ) ){
3271 $list .= classifieds_get_taxonomy_search_tree( $term->children, $selected, $field, $depth+1 );
3272 }
3273 }
3274 return $list;
3275}
3276
3277/*
3278Get last category from the list of categories
3279*/
3280function classifieds_get_last_category( $cats ){
3281 $last = array_pop( $cats );
3282 if( !empty( $last->children ) ){
3283 $last = classifieds_get_last_category( $last->children );
3284 }
3285
3286 return $last;
3287}
3288
3289/*
3290Display additional details of the ad on the frontend
3291*/
3292function classifieds_list_details_find_value( $field, $value ){
3293 $html = '';
3294 $values = explode( "\n", $field->field_values );
3295 if( !empty( $values ) ){
3296 foreach( $values as $value_item ){
3297 if( !empty( $value_item ) ){
3298 $temp = explode( '|', $value_item );
3299 if( $temp[0] == $value ){
3300 $html = '<dt>'.$field->label.'</dt><dd>'.$temp[1].'</dd>';
3301 }
3302 }
3303 }
3304 }
3305
3306 return $html;
3307}
3308
3309/*
3310Display additional details of the ad on the frontend
3311*/
3312function classifieds_list_details( $post_id = '' ){
3313 global $wpdb;
3314 if( empty( $post_id ) ){
3315 $post_id = get_the_ID();
3316 }
3317
3318 $cats = wp_get_object_terms( $post_id, 'ad-category' );
3319 $list = '';
3320
3321 if( !empty( $cats ) ){
3322
3323 $terms_organized = array();
3324 classifieds_sort_terms_hierarchicaly( $cats, $terms_organized );
3325
3326 $cat = classifieds_get_last_category( $terms_organized );
3327 if( empty( $cat ) ){
3328 $cat = array_pop( $cats );
3329 }
3330
3331 $results = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->postmeta} WHERE meta_key = 'fields_for' AND meta_value LIKE %s", '%"'.$cat->slug.'%' ) );
3332
3333 if( !empty( $results ) ){
3334 $list = '<div class="ad-details clearfix"><h3><i class="fa fa-marker"></i>'.esc_html__( 'Details', 'classifieds' ).'</h3><dl class="list-2-col">';
3335 $list_array = array();
3336
3337 $fields = classifieds_get_custom_fields( $results[0]->post_id );
3338 if( !empty( $fields ) ){
3339 foreach( $fields as $field ){
3340
3341 $value = classifieds_get_post_meta( $post_id, $field->name );
3342
3343 if( !empty( $value ) ){
3344 if( $field->type == 'select' ){
3345 $list_array[] = classifieds_list_details_find_value( $field, $value );
3346 $subfields = classifieds_get_custom_subfields( $results[0]->post_id, $field->field_id );
3347 if( !empty( $subfields ) ){
3348 foreach( $subfields as $subfield ){
3349 $value = classifieds_get_post_meta( $post_id, $subfield->name );
3350 if( !empty( $value ) ){
3351 $list_array[] = classifieds_list_details_find_value( $subfield, $value );
3352 }
3353 }
3354 }
3355 }
3356 else{
3357 $list_array[] = '<dt>'.$field->label.'</dt><dd>'.str_replace( "|", ", ", $value ).'</dd>';
3358 }
3359 }
3360
3361 }
3362 }
3363
3364 $values_in_col = ceil( sizeof( $list_array ) / 2 );
3365 for( $i=0; $i<sizeof( $list_array ); $i++ ){
3366 $list .= $list_array[$i];
3367 }
3368
3369 $list .= '</dl></div>';
3370
3371 if( empty( $list_array ) ){
3372 $list = '';
3373 }
3374 }
3375
3376 }
3377
3378 echo $list;
3379}
3380
3381
3382/*
3383Filter ads by radius
3384*/
3385function classifieds_filter_posts_fields( $fields ) {
3386 global $wpdb, $classifieds_slugs;
3387 $longitude = isset( $_GET[$classifieds_slugs['longitude']] ) ? $_GET[$classifieds_slugs['longitude']] : 0;
3388 $latitude = isset( $_GET[$classifieds_slugs['latitude']] ) ? $_GET[$classifieds_slugs['latitude']] : 0;
3389 if( !empty( $longitude ) && !empty( $latitude ) ){
3390 $fields .= ", ( 6371000 *
3391 acos(
3392 cos( radians( {$latitude} ) ) * cos( radians( postmeta_lat.meta_value ) ) *
3393 cos( radians( postmeta_long.meta_value ) - radians( {$longitude} ) ) +
3394 sin( radians( {$latitude} ) ) * sin( radians( postmeta_lat.meta_value ) )
3395 )
3396 ) AS distance";
3397 }
3398 return $fields;
3399}
3400
3401/*
3402Add having test for the radius
3403*/
3404function classifieds_having_radius( $groupby ){
3405 global $wpdb, $classifieds_slugs;
3406 $groupby = " {$wpdb->posts}.ID ";
3407 $radius = isset( $_GET[$classifieds_slugs['radius']] ) ? esc_sql( $_GET[$classifieds_slugs['radius']] ) : 0;
3408
3409 $radius_search_units = classifieds_get_option( 'radius_search_units' );
3410 if( $radius_search_units == 'km' ){
3411 $radius = $radius * 1000;
3412 }
3413 else{
3414 $radius = $radius * 1609.34;
3415 }
3416
3417 $groupby .= " HAVING distance < ".$radius." ";
3418
3419 return $groupby;
3420}
3421
3422/*
3423Join additional fields
3424*/
3425function classifieds_join_radius( $join ){
3426 global $wpdb;
3427 $join .= "LEFT JOIN {$wpdb->prefix}postmeta AS postmeta_long ON $wpdb->posts.ID = postmeta_long.post_id ";
3428 $join .= "LEFT JOIN {$wpdb->prefix}postmeta AS postmeta_lat ON $wpdb->posts.ID = postmeta_lat.post_id ";
3429 return $join;
3430}
3431
3432/*
3433Join additional fields for custom fields
3434*/
3435function classifieds_join_custom_fields( $join ){
3436 global $wpdb;
3437 $counter = 1;
3438 foreach( $_GET as $key => $value ){
3439 $custom_meta_key = substr( $key, 0, 3 );
3440 if( $custom_meta_key == 'cf_' ){
3441 $join .= "LEFT JOIN {$wpdb->prefix}custom_fields_meta AS cf{$counter} ON $wpdb->posts.ID = cf{$counter}.post_id ";
3442 $counter++;
3443 }
3444 }
3445 return $join;
3446}
3447
3448/*
3449Additional WHERE
3450*/
3451function classifieds_where( $where ){
3452 $where .= " AND postmeta_long.meta_key = 'ad_gmap_longitude' AND postmeta_lat.meta_key = 'ad_gmap_latitude'";
3453 return $where;
3454}
3455
3456/*
3457Additional WHERE for custom fields
3458*/
3459function classifieds_where_custom_fields( $where ){
3460 global $wpdb;
3461 $counter = 1;
3462 foreach( $_GET as $key => $value ){
3463 $custom_meta_key = substr( $key, 0, 3 );
3464 if( $custom_meta_key == 'cf_' ){
3465 $custom_meta_key = str_replace( 'cf_', '', $key );
3466 $where .= ' AND ';
3467 $values = explode( ',', $value );
3468 if( sizeof( $values ) > 0 ){
3469 $where .= '( ';
3470 $value_array = array();
3471 foreach( $values as $value ){
3472 $value_array[] = $wpdb->prepare( "cf{$counter}.name = %s AND cf{$counter}.val = %s", $custom_meta_key, $value );
3473 }
3474 $where .= join( ' OR ', $value_array );
3475 $where .= ' ) ';
3476 }
3477 else{
3478 $where .= $wpdb->prepare( "cf{$counter}.name = %s AND cf{$counter}.val = %s ", $custom_meta_key, $values );
3479 }
3480
3481 $counter++;
3482 }
3483 }
3484 return $where;
3485}
3486
3487/*
3488Get ad info for the google marker
3489*/
3490function classifieds_generate_marker_info( $args, $check_cache = false ){
3491 //delete_transient( 'classifieds_home_markers' );
3492 if( $check_cache && get_transient( 'classifieds_home_markers' ) ){
3493 echo get_transient( 'classifieds_home_markers' );
3494 }
3495 else{
3496 global $wpdb;
3497
3498 $markers_html = '<div class="markers hidden">';
3499 $home_map_ads = classifieds_get_option( 'home_map_ads' );
3500 $home_map_ads_source = classifieds_get_option( 'home_map_ads_source' );
3501 $counter = 1;
3502 $has_rows = true;
3503 while( $has_rows ){
3504
3505 $limit = 500;
3506 if( !empty( $home_map_ads ) ){
3507 $limit = min( 500, $home_map_ads );
3508 }
3509 $offset = ( $counter - 1 ) * $limit;
3510
3511 $markers = $wpdb->get_results(
3512 $wpdb->prepare(
3513 "SELECT postmeta1.meta_value AS longitude, postmeta2.meta_value AS latitude, post_title, ID, post_author FROM {$wpdb->posts} AS posts
3514 LEFT JOIN {$wpdb->postmeta} AS postmeta1 ON posts.ID = postmeta1.post_id
3515 LEFT JOIN {$wpdb->postmeta} AS postmeta2 ON postmeta2.post_id = postmeta1.post_id
3516 LEFT JOIN {$wpdb->postmeta} AS postmeta3 ON postmeta3.post_id = postmeta2.post_id
3517 LEFT JOIN {$wpdb->postmeta} AS postmeta4 ON postmeta4.post_id = postmeta3.post_id
3518 ".( $home_map_ads_source !== 'all' ? " LEFT JOIN {$wpdb->postmeta} AS postmeta5 ON postmeta5.post_id = postmeta4.post_id " : '' )."
3519 WHERE post_type = 'ad' AND postmeta1.meta_key = 'ad_gmap_longitude' AND postmeta2.meta_key = 'ad_gmap_latitude' AND
3520 postmeta3.meta_key = 'ad_expire' AND postmeta3.meta_value > %d AND
3521 postmeta4.meta_key = 'ad_visibility' AND postmeta4.meta_value = 'yes'
3522 ".( $home_map_ads_source !== 'all' ? " AND postmeta5.meta_key = 'ad_featured' AND postmeta5.meta_value = '".( esc_sql( $home_map_ads_source ) )."' " : '' )."
3523 ".( !empty( $args ) ? ' AND posts.ID IN ( '.join( $args, ',' ).' ) ' : '' )."
3524 GROUP BY posts.ID LIMIT %d OFFSET %d",
3525 current_time( 'timestamp' ),
3526 $limit,
3527 $offset
3528 )
3529 );
3530
3531 if( !empty( $markers ) ){
3532 $home_map_show_price = classifieds_get_option( 'home_map_show_price' );
3533 foreach( $markers as $marker ){
3534 $ad_gmap_longitude = $marker->longitude;
3535 $ad_gmap_latitude = $marker->latitude;
3536 $permalink = get_permalink( $marker->ID );
3537 $title = $marker->post_title;
3538 if( strlen( $title > 37 ) ){
3539 $title = substr( $title, 0, 37 ).'...';
3540 }
3541 if( !empty( $ad_gmap_longitude ) && !empty( $ad_gmap_latitude ) ){
3542
3543 $icon = '';
3544 $icon = classifieds_get_cat_icon( $marker->ID );
3545 $phone_number = get_post_meta( $marker->ID, 'ad_phone', true );
3546 if( empty( $phone_number ) ){
3547 $phone_number = get_user_meta( $marker->post_author, 'phone_number', true );
3548 }
3549
3550 $markers_html .= '<div class="marker" data-longitude="'.esc_attr__( $ad_gmap_longitude ).'" data-latitude="'.esc_attr__( $ad_gmap_latitude ).'" data-marker-icon="'.esc_attr__( $icon ).'">';
3551
3552 $info_price = '';
3553 if( $home_map_show_price == 'yes' ){
3554 ob_start();
3555 classifieds_get_price( $marker->ID );
3556 $info_price = '
3557 <div class="info-price">
3558 <div class="price-block">
3559 <div class="ad-pricing">
3560 '.ob_get_contents().'
3561 </div>
3562 </div>
3563 </div>
3564 ';
3565 ob_end_clean();
3566 }
3567 $markers_html .= htmlspecialchars('
3568 <div class="info-window clearfix">
3569 '.$info_price.'
3570 <div class="info-image">
3571 <a href="'.esc_url( $permalink ).'" target="_blank">
3572 '.get_the_post_thumbnail( $marker->ID, 'classifieds-map' ).'
3573 </a>
3574 </div>
3575 <div class="info-details">
3576 <a href="'.esc_url( $permalink ).'" target="_blank">'.$title.'</a>
3577 '.( !empty( $phone_number ) ? '<p><i class="fa fa-phone"></i> '.classifieds_format_phones( $phone_number ).'</p>' : '' ).'
3578 </div>
3579 </div>');
3580 $markers_html .= '</div>';
3581 }
3582 }
3583 }
3584 else{
3585 $has_rows = false;
3586 }
3587
3588 if( !empty( $home_map_ads ) && ( $counter * $limit ) >= $home_map_ads ){
3589 $has_rows = false;
3590 }
3591
3592 $counter++;
3593
3594 }
3595 $markers_html .= '</div>';
3596
3597 if( $check_cache ){
3598 $home_map_cache_interval = classifieds_get_option( 'home_map_cache_interval' );
3599 set_transient( 'classifieds_home_markers', $markers_html, 60*60*$home_map_cache_interval );
3600 }
3601
3602 echo $markers_html;
3603 }
3604}
3605
3606/*
3607Count ads by the user
3608*/
3609function classifieds_count_ads_by_user( $user_id ){
3610 return count_user_posts( $user_id , 'ad' );
3611}
3612
3613/*
3614Make user verified
3615*/
3616function classifieds_make_user_verified( $user_id ){
3617 $ads_for_verified = classifieds_get_option( 'ads_for_verified' );
3618 if( !empty( $ads_for_verified ) ){
3619 if( classifieds_count_ads_by_user( $user_id ) >= $ads_for_verified ){
3620 update_user_meta( $user_id, 'is_verified', 'yes' );
3621 }
3622 }
3623}
3624
3625/*
3626Check if user is verified
3627*/
3628function classifieds_is_verified( $user_id ){
3629 $is_verified = get_user_meta( $user_id, 'is_verified', true );
3630 if( $is_verified == 'yes' ){
3631 return true;
3632 }
3633 else{
3634 return false;
3635 }
3636}
3637
3638/*
3639Get verified badge
3640*/
3641function classifieds_get_verified_badge( $user_id ){
3642 if( classifieds_is_verified( $user_id ) ){
3643 echo '<i class="fa fa-check verified" title="'.esc_attr__( 'Verified User', 'classifieds' ).'"></i>';
3644 }
3645}
3646
3647/*
3648Get featured badge
3649*/
3650function classifieds_get_featured_badge( $post_id ){
3651 $ad_featured = get_post_meta( $post_id, 'ad_featured', true );
3652 if( $ad_featured == 'yes' ){
3653 echo '<i class="fa fa-star featured" title="'.esc_attr__( 'Featured Ad', 'classifieds' ).'"></i>';
3654 }
3655}
3656
3657/*
3658Format user phones
3659*/
3660function classifieds_format_phones( $phone ){
3661 if( !empty( $phone ) ){
3662 $last_3 = substr( $phone, -3);
3663 $phone = substr_replace( $phone, 'XXX', -3 );
3664
3665 return '<a href="javascript:;" data-last="'.esc_attr__( $last_3 ).'" class="phone-reveal" title="'.esc_html__( 'Click to reveal number', 'classifieds' ).'">'.$phone.'</a>';
3666 }
3667}
3668
3669/*
3670Submit ask question form
3671*/
3672function classifieds_ask_question(){
3673 $name = isset( $_POST['name'] ) ? $_POST['name'] : '';
3674 $email = isset( $_POST['email'] ) ? $_POST['email'] : '';
3675 $message = isset( $_POST['message'] ) ? $_POST['message'] : '';
3676 $ad_id = isset( $_POST['ad_id'] ) ? esc_sql( $_POST['ad_id'] ) : '';
3677
3678 if( isset( $_POST['captcha'] ) ){
3679
3680 if( !empty( $name ) && !empty( $email ) && !empty( $message ) ){
3681 if( filter_var( $email, FILTER_VALIDATE_EMAIL ) ){
3682 $ad = get_post( $ad_id );
3683 if( !empty( $ad ) ){
3684 $user_data = get_userdata( $ad->post_author );
3685 $headers[] = 'From: '.$name.' <'.$email.'>';
3686 $headers[] = 'Reply-To: '.$name.' <'.$email.'>';
3687 $subject = esc_html__( 'Question About - ', 'classifieds' ).$ad->post_title;
3688 $message = preg_replace( "!\r?\n!", "\n", $message);
3689 $message = $message."\n\n".esc_html__( '--------', 'classifieds' )."\n\n".esc_html__( 'This message is sent using as question form on ', 'classifieds' ).get_bloginfo( 'name' ).esc_html__(' site. You can reply on this message directly.', 'classifieds');
3690 $info = @wp_mail( $user_data->user_email, $subject, $message, $headers );
3691 if( $info ){
3692 $message = '<div class="alert alert-success">'.esc_html__( 'Your question is sent.', 'classifieds' ).'</div>';
3693 }
3694 else{
3695 $message = '<div class="alert alert-danger">'.esc_html__( 'Unable to send the question. Try again..', 'classifieds' ).'</div>';
3696 }
3697 }
3698 else{
3699 $message = '<div class="alert alert-danger">'.esc_html__( 'Ad is invalid.', 'classifieds' ).'</div>';
3700 }
3701 }
3702 else{
3703 $message = '<div class="alert alert-danger">'.esc_html__( 'Email is invalid.', 'classifieds' ).'</div>';
3704 }
3705 }
3706 else{
3707 $message = '<div class="alert alert-danger">'.esc_html__( 'All fields are required.', 'classifieds' ).'</div>';
3708 }
3709 }
3710 else{
3711 $message = '<div class="alert alert-danger">'.esc_html__( 'Captcha is wrong', 'classifieds' ).'</div>';
3712 }
3713
3714 $response = array(
3715 'message' => $message,
3716 );
3717
3718 echo json_encode( $response );
3719 die();
3720}
3721add_action('wp_ajax_ask_question', 'classifieds_ask_question');
3722add_action('wp_ajax_nopriv_ask_question', 'classifieds_ask_question');
3723
3724/*
3725Submit report form
3726*/
3727function classifieds_report(){
3728 $name = isset( $_POST['name'] ) ? $_POST['name'] : '';
3729 $email = isset( $_POST['email'] ) ? $_POST['email'] : '';
3730 $message = isset( $_POST['message'] ) ? $_POST['message'] : '';
3731 $ad_id = isset( $_POST['ad_id'] ) ? esc_sql( $_POST['ad_id'] ) : '';
3732
3733 if( isset( $_POST['captcha'] ) ){
3734
3735 if( !empty( $name ) && !empty( $email ) && !empty( $message ) ){
3736 if( filter_var( $email, FILTER_VALIDATE_EMAIL ) ){
3737 $ad = get_post( $ad_id );
3738 if( !empty( $ad ) ){
3739 $headers = array();
3740 $headers[] = "MIME-Version: 1.0";
3741 $headers[] = "Content-Type: text/html; charset=UTF-8";
3742 $subject = esc_html__( 'Report Ad - ', 'classifieds' ).$ad->post_title;
3743
3744 $message = preg_replace( "!\r?\n!", "<br />", $message);
3745 $message = $message."<br /><br />".esc_html__( '--------', 'classifieds' )."<br /><br />".esc_html__( 'Reporting Ad: ', 'classifieds'). '<a href="'.get_permalink( $ad_id ).'" target="_blank">'.get_the_title( $ad_id ).'</a> '.esc_html__( 'by', 'classifieds' ).' '.$name.' ('.$email.')';
3746
3747 $new_offer_email = classifieds_get_option( 'new_offer_email' );
3748
3749 $info = @wp_mail( $new_offer_email, $subject, $message, $headers );
3750 if( $info ){
3751 $message = '<div class="alert alert-success">'.esc_html__( 'Report is sent.', 'classifieds' ).'</div>';
3752 }
3753 else{
3754 $message = '<div class="alert alert-danger">'.esc_html__( 'Unable to send the report. Try again.', 'classifieds' ).'</div>';
3755 }
3756 }
3757 else{
3758 $message = '<div class="alert alert-danger">'.esc_html__( 'Ad is invalid.', 'classifieds' ).'</div>';
3759 }
3760 }
3761 else{
3762 $message = '<div class="alert alert-danger">'.esc_html__( 'Email is invalid.', 'classifieds' ).'</div>';
3763 }
3764 }
3765 else{
3766 $message = '<div class="alert alert-danger">'.esc_html__( 'All fields are required.', 'classifieds' ).'</div>';
3767 }
3768 }
3769 else{
3770 $message = '<div class="alert alert-danger">'.esc_html__( 'Captcha is wrong', 'classifieds' ).'</div>';
3771 }
3772
3773 $response = array(
3774 'message' => $message,
3775 );
3776
3777 echo json_encode( $response );
3778 die();
3779}
3780add_action('wp_ajax_report', 'classifieds_report');
3781add_action('wp_ajax_nopriv_report', 'classifieds_report');
3782
3783/*
3784Get icon of the category
3785*/
3786function classifieds_get_cat_icon( $post_id = '' ){
3787 if( empty( $post_id ) ){
3788 $post_id = get_the_ID();
3789 }
3790 $cats = wp_get_post_terms( $post_id, 'ad-category' );
3791 if( !empty( $cats ) ){
3792 foreach( $cats as $cat ){
3793 if( $cat->parent == 0 ){
3794 $term_meta = get_option('taxonomy_'.$cat->slug);
3795 $icon = isset( $term_meta['category_marker'] ) ? $term_meta['category_marker'] : '';
3796 if( !empty( $icon ) ){
3797 if( !empty( $icon ) ){
3798 $icon_data = wp_get_attachment_image_src( $icon, 'full' );
3799 $icon = $icon_data[0];
3800 }
3801 return $icon;
3802 }
3803 }
3804 }
3805 }
3806}
3807
3808/*
3809Get amount for the submit of the ad.
3810*/
3811function classifieds_ad_payment_amount( $post_id ){
3812 $ad_featured = get_post_meta( $post_id, 'ad_featured', true );
3813 $basic_ad_price = classifieds_get_option( 'basic_ad_price' );
3814 $featured_ad_price = classifieds_get_option( 'featured_ad_price' );
3815
3816 $amount = 0;
3817
3818 if( !empty( $basic_ad_price ) ){
3819 $amount += $basic_ad_price;
3820 }
3821
3822 if( !empty( $featured_ad_price ) && $ad_featured == 'yes' ){
3823 $amount += $featured_ad_price;
3824 }
3825
3826 return $amount;
3827}
3828
3829/*
3830Save changes of the ad.
3831*/
3832function classifieds_update_ad(){
3833 $ad_terms_text = classifieds_get_option( 'ad_terms' );
3834 if( empty( $ad_terms_text ) ){
3835 $_POST['ad_terms'] = 1;
3836 }
3837
3838 $is_expired = !empty( $_POST['is_expired'] ) ? true : false;
3839 $ad_title = !empty( $_POST['ad_title'] ) ? $_POST['ad_title'] : '';
3840 $featured_image = !empty( $_POST['featured_image'] ) ? $_POST['featured_image'] : '';
3841 $ad_description = !empty( $_POST['ad_description'] ) ? $_POST['ad_description'] : '';
3842 $ad_tags = !empty( $_POST['ad_tags'] ) ? $_POST['ad_tags'] : '';
3843 $ad_price = !empty( $_POST['ad_price'] ) ? $_POST['ad_price'] : '';
3844 $ad_phone = !empty( $_POST['ad_phone'] ) ? $_POST['ad_phone'] : '';
3845 $ad_discounted_price = !empty( $_POST['ad_discounted_price'] ) ? $_POST['ad_discounted_price'] : '';
3846 $ad_call_for_price = isset( $_POST['ad_call_for_price'] ) ? 1 : 0;
3847 $ad_gmap_longitude = !empty( $_POST['ad_gmap_longitude'] ) ? $_POST['ad_gmap_longitude'] : '';
3848 $ad_gmap_latitude = !empty( $_POST['ad_gmap_latitude'] ) ? $_POST['ad_gmap_latitude'] : '';
3849 $ad_category = !empty( $_POST['ad_category'] ) ? $_POST['ad_category'] : '';
3850 $ad_images = !empty( $_POST['ad_images'] ) ? $_POST['ad_images'] : array();
3851 $ad_videos = !empty( $_POST['ad_videos'] ) ? $_POST['ad_videos'] : array();
3852 $ad_featured = isset( $_POST['ad_featured'] ) ? 'yes' : 'no';
3853 $ad_views = isset( $_POST['ad_views'] ) ? $_POST['ad_views'] : 0;
3854 $ad_visibility = !empty( $_POST['ad_visibility'] ) ? $_POST['ad_visibility'] : 'yes';
3855 $post_id = !empty( $_POST['post_id'] ) ? $_POST['post_id'] : 0;
3856 $ad_terms = isset( $_POST['ad_terms'] ) ? true : false;
3857
3858
3859 if( $ad_terms ){
3860 if( !empty( $ad_title ) ){
3861 if( !empty( $ad_description ) ){
3862 if( !empty( $ad_gmap_longitude ) && !empty( $ad_gmap_longitude ) ){
3863 if( !empty( $ad_category ) ){
3864 $post_args = array(
3865 'post_type' => 'ad',
3866 'post_title' => $ad_title,
3867 'post_content' => $ad_description,
3868 'post_status' => 'draft'
3869 );
3870
3871 if( $post_id !== 0 ){
3872
3873 if( !$is_expired ){
3874 $post_args['post_parent'] = $post_id;
3875 }
3876
3877 $old_drafts = get_posts(array(
3878 'post_type' => 'ad',
3879 'posts_per_page' => '-1',
3880 'post_status' => 'any',
3881 'post_parent' => $post_id
3882 ));
3883 if( !empty( $old_drafts ) ){
3884 foreach( $old_drafts as $old_draft ){
3885 wp_delete_post( $old_draft->ID, true );
3886 }
3887 }
3888 update_post_meta( $post_id, 'ad_visibility', $ad_visibility );
3889 }
3890
3891 $all_cats = array();
3892 $all_to_assign = get_ancestors( $ad_category, 'ad-category' );
3893 if( !empty( $all_to_assign ) ){
3894 $all_cats = $all_to_assign;
3895 }
3896 $all_cats[] = $ad_category;
3897 $post_args['tax_input']['ad-category'] = $all_cats;
3898
3899 $post_args['tax_input']['ad-tag'] = explode( ',', $ad_tags );
3900
3901 $post_id = wp_insert_post( $post_args );
3902
3903 if( $is_expired ){
3904 delete_post_meta( $_POST['post_id'], 'ad_expire' );
3905 classifieds_copy_custom_values( $post_id, $_POST['post_id'] );
3906 wp_delete_post( $_POST['post_id'], true );
3907 $_POST['post_id'] = 0;
3908 }
3909
3910 if( !empty( $featured_image ) ){
3911 set_post_thumbnail( $post_id, $featured_image );
3912 }
3913
3914 update_post_meta( $post_id, 'ad_phone', $ad_phone );
3915 if( !empty( $ad_price ) ){
3916 update_post_meta( $post_id, 'ad_price', $ad_price );
3917 }
3918 if( !empty( $ad_call_for_price ) ){
3919 delete_post_meta( $post_id, 'ad_price' );
3920 update_post_meta( $post_id, 'ad_call_for_price', 1 );
3921 }
3922
3923 if( !empty( $ad_discounted_price ) ){
3924 update_post_meta( $post_id, 'ad_discounted_price', $ad_discounted_price );
3925 }
3926 update_post_meta( $post_id, 'ad_gmap_longitude', $ad_gmap_longitude );
3927 update_post_meta( $post_id, 'ad_gmap_latitude', $ad_gmap_latitude );
3928 update_post_meta( $post_id, 'ad_visibility', $ad_visibility );
3929 update_post_meta( $post_id, 'ad_views', $ad_views );
3930
3931 delete_post_meta( $post_id, 'ad_images' );
3932 if( !empty( $ad_images ) ){
3933 $ad_images_arranged = array();
3934 $ad_images_arranged = array();
3935 $counter = 0;
3936 foreach ( $ad_images as $ad_image ) {
3937 $ad_images_arranged['sm-field-'.$counter] = $ad_image;
3938 $counter++;
3939 }
3940 $ad_images = array( serialize( $ad_images_arranged ) );
3941 update_post_meta( $post_id, 'ad_images', implode( "", $ad_images ) );
3942 }
3943
3944 delete_post_meta( $post_id, 'ad_videos' );
3945 if( !empty( $ad_videos ) ){
3946 foreach( $ad_videos as $ad_video ){
3947 if( !empty( $ad_video ) ){
3948 add_post_meta( $post_id, 'ad_videos', $ad_video );
3949 }
3950 }
3951 }
3952
3953 update_post_meta( $post_id, 'ad_featured', $ad_featured );
3954
3955 if( $_POST['post_id'] == 0 ){
3956 $amount = classifieds_ad_payment_amount( $post_id );
3957 if( empty( $amount ) ){
3958 update_post_meta( $post_id, 'ad_paid', 'yes' );
3959 $response = '<div class="alert alert-success">'.esc_html__( 'Add has been added to the review queue', 'classifieds' ).'</div>';
3960 }
3961 else{
3962 update_post_meta( $post_id, 'ad_paid', 'no' );
3963 $response = classifieds_create_payments( $post_id, $amount );
3964 }
3965 classifieds_inform_admin( $post_id, $is_expired );
3966 }
3967 else{
3968 $response = '<div class="alert alert-success">'.esc_html__( 'Add has been edited successfully', 'classifieds' ).'</div>';
3969 classifieds_update_parent( $_POST['post_id'], $post_id );
3970 }
3971
3972 }
3973 else{
3974 $response = '<div class="alert alert-danger">'.esc_html__( 'Category of the add is required', 'classifieds' ).'</div>';
3975 }
3976 }
3977 else{
3978 $response = '<div class="alert alert-danger">'.esc_html__( 'Location of the add is required', 'classifieds' ).'</div>';
3979 }
3980 }
3981 else{
3982 $response = '<div class="alert alert-danger">'.esc_html__( 'Description of the add is required', 'classifieds' ).'</div>';
3983 }
3984 }
3985 else{
3986 $response = '<div class="alert alert-danger">'.esc_html__( 'Ad title is required', 'classifieds' ).'</div>';
3987 }
3988 }
3989 else{
3990 $response = '<div class="alert alert-danger">'.esc_html__( 'You must accept terms and conditions in order to submit your ad.', 'classifieds' ).'</div>';
3991 }
3992
3993 echo json_encode( array( 'message' => $response ) );
3994 die();
3995}
3996add_action('wp_ajax_update_ad', 'classifieds_update_ad');
3997add_action('wp_ajax_nopriv_update_ad', 'classifieds_update_ad');
3998
3999/*
4000on edit publish update main ad
4001*/
4002function classifieds_update_parent( $post_parent_id, $post_id ){
4003 global $wpdb;
4004 $post = get_post( $post_id );
4005 $post_parent = get_post( $post_parent_id );
4006 $post_args = array(
4007 'ID' => $post_parent_id,
4008 'post_type' => 'ad',
4009 'post_title' => $post->post_title,
4010 'post_content' => $post->post_content,
4011 'post_date_gmt' => $post_parent->post_date_gmt,
4012 'post_date' => $post_parent->post_date,
4013 );
4014
4015 wp_update_post( $post_args );
4016
4017 $categories = wp_get_post_terms( $post_id, 'ad-category', array( 'fields' => 'ids' ) );
4018 wp_set_post_terms( $post_parent_id, $categories, 'ad-category' );
4019
4020 $tags = wp_get_post_terms( $post_id, 'ad-tag', array( 'fields' => 'ids' ) );
4021 wp_set_post_terms( $post_parent_id, $tags, 'ad-tag' );
4022
4023 $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->postmeta} WHERE post_id = %d AND meta_key != 'ad_expire'", $post_parent_id ) );
4024 classifieds_copy_custom_values( $post_parent_id, $post->ID );
4025
4026 wp_delete_post( $post->ID, true );
4027}
4028
4029/*
4030Copy custom field values
4031*/
4032function classifieds_copy_custom_values( $to, $from ){
4033 global $wpdb;
4034 $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->postmeta} SET post_id = %d WHERE post_id = %d", $to, $from ) );
4035}
4036
4037/*
4038Create list of payments for the submit of ad
4039*/
4040function classifieds_create_payments( $ad_id, $amount ){
4041 $payments = '<div class="alert">'.esc_html__( 'Select your payment method:', 'classifieds' ).'</div>';
4042 $permalink = classifieds_get_permalink_by_tpl( 'page-tpl_my_profile' );
4043 $currency = classifieds_get_option( 'main_unit_abbr' );
4044 /* CHECK IF PAYPAL PAYMENT IS AVAILABLE */
4045 $paypal_username = classifieds_get_option( 'paypal_username' );
4046 if( !empty( $paypal_username ) ){
4047 $paypal = new PayPal(array(
4048 'username' => $paypal_username,
4049 'password' => classifieds_get_option( 'paypal_password' ),
4050 'signature' => classifieds_get_option( 'paypal_signature' ),
4051 'cancelUrl' => add_query_arg( array( 'cancel' => 'yes', 'ad_id' => $ad_id ), $permalink ),
4052 'returnUrl' => add_query_arg( array( 'payment' => 'paypal', 'ad_id' => $ad_id ), $permalink ),
4053 ));
4054
4055 $pdata = array(
4056 'PAYMENTREQUEST_0_PAYMENTACTION' => "SALE",
4057 'L_PAYMENTREQUEST_0_NAME0' => esc_html__( 'Ad Submission', 'classifieds' ),
4058 'L_PAYMENTREQUEST_0_NUMBER0' => uniqid(),
4059 'L_PAYMENTREQUEST_0_DESC0' => esc_html__( 'Payment for displaying ad on website.', 'classifieds' ),
4060 'L_PAYMENTREQUEST_0_AMT0' => $amount,
4061 'L_PAYMENTREQUEST_0_QTY0' => 1,
4062 'NOSHIPPING' => 1,
4063 'PAYMENTREQUEST_0_CURRENCYCODE' => $currency,
4064 'PAYMENTREQUEST_0_AMT' => $amount
4065 );
4066
4067 $response = $paypal->SetExpressCheckout( $pdata );
4068 if( !isset( $response['error'] ) ){
4069 $payments .= '<a href="'.esc_url( $response['url'] ).'"><img src="'.get_template_directory_uri().'/images/paypal.png" alt="" /></a>';
4070 }
4071 }
4072
4073 /* CHECK IF STRIPE PAYMENT IS AVAILABLE */
4074 $stripe_pk_client_id = classifieds_get_option( 'stripe_pk_client_id' );
4075 if( !empty( $stripe_pk_client_id ) ){
4076 $site_logo = classifieds_get_option( 'site_logo' );
4077 $logo_link = '';
4078 if( !empty( $site_logo['url'] ) ){
4079 $logo_link = $site_logo['url'];
4080 }
4081 $stripe_amount = $amount * 100;
4082
4083 $payments .= '<a href="javascript:;" class="stripe-payment" data-genearting_string="'.esc_attr__( 'Processing...', 'classifieds' ).'" data-pk="'.esc_attr__( $stripe_pk_client_id ).'" data-ad_id="'.esc_attr__( $ad_id ).'" data-image="'.esc_url( $logo_link ).'" data-name="'.esc_attr__( 'Ad Submission', 'classifieds' ).'" data-description="'.esc_attr__( 'Payment for displaying ad on website.', 'classifieds' ).'" data-amount="'.esc_attr__( $stripe_amount ).'" data-currency="'.esc_attr__( $currency ).'">
4084 <img src="'.get_template_directory_uri().'/images/stripe.png" alt="" />
4085 </a>';
4086 }
4087 /* CHECK IF SKRILL PAYMENT IS AVAILABLE */
4088 $skrill_owner_mail = classifieds_get_option( 'skrill_owner_mail' );
4089 if( !empty( $skrill_owner_mail ) ){
4090 $payments .= '
4091 <a href="javascript:;" class="skrill-payment">
4092 <img src="'.get_template_directory_uri().'/images/skrill.png" alt="" />
4093 </a>
4094 <form class="hidden skrill-form" action="https://www.moneybookers.com/app/payment.pl" method="post">
4095 <input type="hidden" name="pay_to_email" value="'.esc_attr__( $skrill_owner_mail ).'"/>
4096 <input type="hidden" name="status_url" value="'.add_query_arg( array( 'payment' => 'skrill-verify', 'ad_id' => $ad_id ), home_url( '/index.php' ) ).'"/>
4097 <input type="hidden" name="language" value="EN"/>
4098 <input type="hidden" name="return_url" value="'.add_query_arg( array( 'payment' => 'skrill', 'ad_id' => $ad_id ), $permalink ).'"/>
4099 <input type="hidden" name="amount" value="'.esc_attr__( $amount ).'"/>
4100 <input type="hidden" name="currency" value="'.esc_attr__( $currency ).'"/>
4101 <input type="hidden" name="detail1_text " value="'.esc_attr__( 'Ad Submission', 'classifieds' ).'"/>
4102 </form>
4103 ';
4104 }
4105
4106 /* CHECK IF BANK TRANSFER PAYMENT IS AVAILABLE */
4107 $bank_name = classifieds_get_option( 'bank_name' );
4108 if( !empty( $bank_name ) ){
4109 $payments .= '
4110 <a href="'.esc_url( add_query_arg( array( 'payment' => 'bank' ), $permalink ) ).'">
4111 <img src="'.get_template_directory_uri().'/images/bank.png" alt="" />
4112 </a>';
4113 }
4114
4115 /* CHECK IF PAYU PAYMENT IS AVAILABLE */
4116 $payu_merchant_key = classifieds_get_option( 'payu_merchant_key' );
4117 if( !empty( $payu_merchant_key ) ){
4118 $surl = add_query_arg( array( 'payment' => 'payu', 'ad_id' => $ad_id ), $permalink );
4119 $payments .= '<a href="javascript:;" class="payu-initiate"><img src="'.get_template_directory_uri().'/images/payu.png" alt="" /></a>'.classifieds_payu_form( $ad_id, $surl );
4120 }
4121
4122 /* CHECK IF IDEAL IS AVAILABLE */
4123 $mollie_id = classifieds_get_option( 'mollie_id' );
4124 if( !empty( $mollie_id ) ){
4125 $iDEAL = new Mollie_iDEAL_Payment ( $mollie_id );
4126 $ideal_mode = classifieds_get_option( 'ideal_mode' );
4127 if( $ideal_mode == 'test' ){
4128 $iDEAL->setTestmode(true);
4129 }
4130
4131 $bank_array = $iDEAL->getBanks();
4132 if( $bank_array ){
4133 $payments .= '<a href="javascript:;" class="submit-ideal-payment"><img src="'.get_template_directory_uri().'/images/ideal.png" alt="" /></a>';
4134 $payments .= '<form method="post" class="ideal-payment">
4135 <select name="bank_id">
4136 <option value="">'.esc_html__( 'Select Your Bank', 'classifieds' ).'</option>';
4137 foreach( $bank_array as $bank_id => $bank_name ){
4138 $payments .= '<option value="'.esc_attr__( $bank_id ).'">'.$bank_name.'</option>';
4139 }
4140 $payments .= '<input type="hidden" name="ad_id" value="'.esc_attr__( $ad_id ).'"><input type="hidden" name="action" value="ideal_link"></select></form>';
4141 }
4142 }
4143
4144 return '<div class="payments">'.$payments.'</div>';
4145
4146}
4147
4148
4149function classifieds_payu_form( $ad_id, $surl = '' ){
4150
4151 if( empty( $ad_id ) ){
4152 $ad_id = $_POST['ad_id'];
4153 }
4154 if( empty( $surl ) ){
4155 $surl = $_POST['surl'];
4156 }
4157
4158 $return = '';
4159 $amount = classifieds_ad_payment_amount( $ad_id );
4160 if( !empty( $amount ) ){
4161 $buyer_id = get_current_user_id();
4162 $first_name = get_user_meta( $buyer_id, 'first_name', true );
4163 $phone_number = get_user_meta( $buyer_id, 'phone_number', true );
4164
4165 if( isset( $_POST['payu_name'] ) ){
4166 $first_name = $_POST['payu_name'];
4167 update_user_meta( $buyer_id, 'first_name', $first_name );
4168 }
4169 if( isset( $_POST['payu_phone'] ) ){
4170 $phone_number = $_POST['payu_phone'];
4171 update_user_meta( $buyer_id, 'phone_number', $phone_number );
4172 }
4173 if( empty( $first_name ) || empty( $phone_number ) ){
4174 $return = '
4175 <form class="payu-form payu-additional hidden">
4176 '.( empty( $first_name ) ? '<label for="payu_name">'.esc_html__( 'First Name', 'classifieds' ).'</label><input type="text" id="payu_name" name="payu_name" class="form-control">' : '' ).'
4177 '.( empty( $phone_number ) ? '<label for="payu_phone">'.esc_html__( 'Phone Number', 'classifieds' ).'</label><input type="text" id="payu_phone" name="payu_phone" class="form-control">' : '' ).'
4178 <input type="hidden" name="ad_id" value="'.esc_attr__( $ad_id ).'">
4179 <input type="hidden" name="surl" value="'.$surl.'">
4180 <input type="hidden" name="action" value="payu_additional" />
4181 <a href="javascript:;" class="btn payu-additional-info">'.esc_html__( 'Process', 'classifieds' ).'</a>
4182 </form>
4183 ';
4184 }
4185 else{
4186 $current_user = wp_get_current_user();
4187 $payu_merchant_key = classifieds_get_option( 'payu_merchant_key' );
4188 $payu_merchant_salt = classifieds_get_option( 'payu_merchant_salt' );
4189
4190 $values = array(
4191 'key' => $payu_merchant_key,
4192 'txnid' => substr(hash('sha256', mt_rand() . microtime()), 0, 20),
4193 'amount' => $amount,
4194 'productinfo' => esc_html__( 'Ad Submission', 'classifieds' ),
4195 'firstname' => $first_name,
4196 'email' => $current_user->user_email
4197 );
4198
4199 $hashSequence = "key|txnid|amount|productinfo|firstname|email|udf1|udf2|udf3|udf4|udf5|udf6|udf7|udf8|udf9|udf10";
4200 $hashVarsSeq = explode('|', $hashSequence);
4201 $hash_string = '';
4202 foreach($hashVarsSeq as $hash_var) {
4203 $hash_string .= isset($values[$hash_var]) ? $values[$hash_var] : '';
4204 $hash_string .= '|';
4205 }
4206 $hash_string .= $payu_merchant_salt;
4207
4208 $hash = strtolower(hash('sha512', $hash_string));
4209 $payu_mode = classifieds_get_option( 'payu_mode' );
4210
4211 $return = '
4212 <form class="payu-form '.( !empty( $_POST['ad_id'] ) ? 'payu-submit' : 'payu-submit-click' ).'" action="https://'.$payu_mode.'.payu.in/_payment" method="post">
4213 <input type="hidden" name="amount" value="'.esc_attr__( $values['amount'] ).'" />
4214 <input type="hidden" name="productinfo" value="'.$values['productinfo'].'" />
4215 <input type="hidden" name="firstname" value="'.esc_attr__( $values['firstname'] ).'" />
4216 <input type="hidden" name="email" value="'.esc_attr__( $values['email'] ).'" />
4217 <input type="hidden" name="surl" value="'.$surl.'" />
4218 <input type="hidden" name="furl" value="'.$surl.'" />
4219 <input type="hidden" name="service_provider" value="payu_paisa" />
4220 <input type="hidden" name="key" value="'.esc_attr__( $payu_merchant_key ).'" />
4221 <input type="hidden" name="hash" value="'.$hash.'"/>
4222 <input type="hidden" name="txnid" value="'.esc_attr__( $values['txnid'] ).'" />
4223 <input type="hidden" name="phone" value="'.esc_attr__( $phone_number ).'" />
4224 </form>
4225 ';
4226 }
4227 }
4228 if( !empty( $_POST['surl'] ) ){
4229 echo $return;
4230 die();
4231 }
4232 else{
4233 return $return;
4234 }
4235}
4236add_action('wp_ajax_payu_additional', 'classifieds_payu_form');
4237add_action('wp_ajax_nopriv_payu_additional', 'classifieds_payu_form');
4238
4239/*
4240Listen for the payment gateways returns
4241*/
4242function classifieds_payment_result(){
4243 $payment = '';
4244 if( isset( $_GET['payment'] ) ){
4245 $payment = $_GET['payment'];
4246 }
4247 else if( isset( $_POST['payment'] ) ){
4248 $payment = $_POST['payment'];
4249 }
4250 switch( $payment ){
4251 case 'paypal' : $response = classifieds_pay_with_paypal(); break;
4252 case 'payu' : $response = classifieds_pay_with_payu(); break;
4253 case 'skrill' : $response = classifieds_pay_with_skrill(); break;
4254 case 'skrill-verify' : $response = classifieds_skrill_payment_confirmation(); break;
4255 case 'bank' : $response = classifieds_pay_with_bank(); break;
4256 case 'ideal' : $response = classifieds_pay_with_ideal(); break;
4257 case 'ideal-verify' : $response = classifieds_ideal_payment_confirmation(); break;
4258 default : $response = '';
4259 }
4260
4261 return $response;
4262}
4263
4264/*
4265Mark ad as paid after successfull payment check
4266*/
4267function classifieds_mark_ad_as_paid( $ad_id ){
4268 update_post_meta( $ad_id, 'ad_paid', 'yes' );
4269}
4270
4271
4272/*
4273Do PayPal payment processing
4274*/
4275function classifieds_pay_with_paypal(){
4276 if( isset( $_GET['ad_id'] ) ){
4277 $ad_id = $_GET['ad_id'];
4278 $amount = classifieds_ad_payment_amount( $ad_id );
4279
4280 if( !empty( $amount ) ){
4281 $paypal = new PayPal(array(
4282 'username' => classifieds_get_option( 'paypal_username' ),
4283 'password' => classifieds_get_option( 'paypal_password' ),
4284 'signature' => classifieds_get_option( 'paypal_signature' ),
4285 'cancelUrl' => add_query_arg( array( 'cancel' => 'yes', 'ad_id' => $ad_id ), classifieds_get_permalink_by_tpl( 'page-tpl_register_store' ) ),
4286 'returnUrl' => add_query_arg( array( 'payment' => 'paypal', 'ad_id' => $ad_id ), classifieds_get_permalink_by_tpl( 'page-tpl_register_store' ) ),
4287 ));
4288
4289 $pdata = array(
4290 'TOKEN' => $_GET['token'],
4291 'PAYERID' => $_GET['PayerID'],
4292 'PAYMENTREQUEST_0_PAYMENTACTION' => "SALE",
4293 'L_PAYMENTREQUEST_0_NAME0' => esc_html__( 'Ad Submission', 'classifieds' ),
4294 'L_PAYMENTREQUEST_0_NUMBER0' => uniqid(),
4295 'L_PAYMENTREQUEST_0_DESC0' => esc_html__( 'Payment for displaying ad on website.', 'classifieds' ),
4296 'L_PAYMENTREQUEST_0_AMT0' => $amount,
4297 'L_PAYMENTREQUEST_0_QTY0' => 1,
4298 'NOSHIPPING' => 1,
4299 'PAYMENTREQUEST_0_CURRENCYCODE' => classifieds_get_option( 'main_unit_abbr' ),
4300 'PAYMENTREQUEST_0_AMT' => $amount
4301 );
4302 $response = $paypal->DoExpressCheckoutPayment( $pdata );
4303 if( !isset( $response['error'] ) && !isset( $response['L_ERRORCODE0'] ) ){
4304 classifieds_mark_ad_as_paid( $ad_id );
4305 return '<div class="alert alert-success no-margin">'.esc_html__( 'Your ad is successfully paid. After review you will receive information about it.', 'classifieds' ).'</div>';
4306 }
4307 else if( isset( $response['L_ERRORCODE0'] ) && $response['L_ERRORCODE0'] === '11607' ){
4308 return '<div class="alert alert-danger no-margin">'.esc_html__( 'You have already registered store with this tranaction ID.', 'classifieds' ).'</div>';
4309 }
4310 else{
4311 return '<div class="alert alert-danger no-margin">'.esc_html__( 'There was an error processing yor request. Please contact administration of the site with this error message:', 'classifieds' ).'<br /><strong>'.$response['error'].'</strong></div>';
4312 }
4313 }
4314 else{
4315 return '<div class="alert alert-danger no-margin">'.esc_html__( 'Wrong ad', 'classifieds' ).'</div>';
4316 }
4317 }
4318
4319}
4320
4321/*
4322Process payu payment
4323*/
4324function classifieds_pay_with_payu(){
4325 $status = $_POST["status"];
4326 $firstname = $_POST["firstname"];
4327 $amount = (string)$_POST["amount"];
4328 $txnid = $_POST["txnid"];
4329 $posted_hash = $_POST["hash"];
4330 $key = $_POST["key"];
4331 $productinfo = $_POST["productinfo"];
4332 $email = $_POST["email"];
4333 $ad_id = $_GET['ad_id'];
4334 $salt = classifieds_get_option( 'payu_merchant_salt' );
4335
4336 $amount_test = classifieds_ad_payment_amount( $ad_id );
4337 if( !empty( $amount_test ) ){
4338
4339 $retHashSeq = $salt.'|'.$status.'|||||||||||'.$email.'|'.$firstname.'|'.$productinfo.'|'.$amount.'|'.$txnid.'|'.$key;
4340 $hash = hash( "sha512", $retHashSeq );
4341
4342 if ( $hash != $posted_hash ) {
4343 return '<div class="alert alert-danger">'.esc_html__( 'Invalid Transaction. Please try again', 'classifieds' ).'</strong></div>';
4344 }
4345 else {
4346 classifieds_mark_ad_as_paid( $ad_id );
4347 return '<div class="alert alert-success no-margin">'.esc_html__( 'Your ad is successfully paid. After review you will receive information about it.', 'classifieds' ).'</div>';
4348 }
4349 }
4350 else{
4351 return '<div class="alert alert-danger">'.esc_html__( 'Offer is no longer available', 'classifieds' ).'</strong></div>';
4352 }
4353}
4354
4355/*
4356Do Stripe payment processing
4357*/
4358function classifieds_pay_with_stripe(){
4359 $token = $_POST['token'];
4360 $ad_id = $_POST['ad_id'];
4361 $amount = classifieds_ad_payment_amount( $ad_id );
4362
4363 if( !empty( $amount ) ){
4364 $response = wp_remote_post( 'https://api.stripe.com/v1/charges', array(
4365 'method' => 'POST',
4366 'timeout' => 45,
4367 'redirection' => 5,
4368 'httpversion' => '1.0',
4369 'blocking' => true,
4370 'headers' => array(
4371 'Authorization' => 'Bearer '.classifieds_get_option( 'stripe_sk_client_id' )
4372 ),
4373 'body' => array(
4374 'amount' => $amount*100,
4375 'currency' => strtolower( classifieds_get_option( 'main_unit_abbr' ) ),
4376 'card' => $token['id'],
4377 'receipt_email' => $token['email'],
4378 ),
4379 'cookies' => array()
4380 ));
4381
4382 if ( is_wp_error( $response ) ) {
4383 $error_message = $response->get_error_message();
4384 echo '<div class="alert alert-danger no-margin">'.esc_html__( 'Something went wrong: ', 'classifieds' ).$error_message.'</div>';
4385 }
4386 else{
4387 $data = json_decode( $response['body'], true );
4388 if( empty( $data['error'] ) ){
4389 classifieds_mark_ad_as_paid( $ad_id );
4390 echo '<div class="alert alert-success stripe-complete no-margin">'.esc_html__( 'Your ad is successfully paid. After review you will receive information about it.', 'classifieds' ).'</div>';
4391 }
4392 else{
4393 echo '<div class="alert alert-danger no-margin">'.json_encode( $data ).'</div>';
4394 }
4395 }
4396 }
4397 else{
4398 echo '<div class="alert alert-danger no-margin">'.esc_html__( 'Wrong store', 'classifieds' ).'</div>';
4399 }
4400 die();
4401}
4402add_action('wp_ajax_pay_with_stripe', 'classifieds_pay_with_stripe');
4403add_action('wp_ajax_nopriv_pay_with_stripe', 'classifieds_pay_with_stripe');
4404
4405/*
4406Do iDEAL payment processing
4407*/
4408function classifieds_pay_with_ideal_link(){
4409 $bank_id = $_POST['bank_id'];
4410 $ad_id = $_POST['ad_id'];
4411 $amount = classifieds_ad_payment_amount( $ad_id );
4412 $permalink = classifieds_get_permalink_by_tpl( 'page-tpl_my_profile' );
4413
4414 if( $amount ){
4415
4416 $mollie_id = classifieds_get_option( 'mollie_id' );
4417 $return_url = add_query_arg( array( 'payment' => 'ideal', 'ad_id' => $ad_id ), $permalink );
4418 $report_url = add_query_arg( array( 'payment' => 'ideal-verify', 'ad_id' => $ad_id ), home_url( '/index.php' ) );
4419 $iDEAL = new Mollie_iDEAL_Payment ( $mollie_id );
4420 $ideal_mode = classifieds_get_option( 'ideal_mode' );
4421 if( $ideal_mode == 'test' ){
4422 $iDEAL->setTestmode(true);
4423 }
4424
4425 $payment = $iDEAL->createPayment( $bank_id, $amount*100, esc_html__( 'Payment for displaying products via feed.', 'classifieds' ), $return_url, $report_url );
4426
4427 if( $payment ){
4428 echo $iDEAL->getBankURL();
4429 }
4430 else{
4431 echo '<div class="alert alert-danger no-margin">'.esc_html__( 'Could not retrive bank URL', 'classifieds' ).' '.$iDEAL->getErrorMessage().'</div>';
4432 }
4433
4434 }
4435 else{
4436 echo '<div class="alert alert-danger no-margin">'.esc_html__( 'Wrong store', 'classifieds' ).'</div>';
4437 }
4438 die();
4439}
4440add_action('wp_ajax_ideal_link', 'classifieds_pay_with_ideal_link');
4441add_action('wp_ajax_nopriv_ideal_link', 'classifieds_pay_with_ideal_link');
4442
4443/*
4444Return message for the iDEAL confirmation
4445*/
4446function classifieds_pay_with_ideal(){
4447 return '<div class="alert alert-success clearfix">'.esc_html__( 'Once iDEAL confirms payment ad will be added to review proces. After it you will receive information about it.', 'classifieds' ).'</div>';
4448}
4449
4450/*
4451Inform user once iDEAL returns result
4452*/
4453function classifieds_ideal_payment_confirmation(){
4454 if( isset( $_GET['ad_id'] ) && isset( $_GET['transaction_id'] ) ){
4455 global $wpdb;
4456 $ad_id = $_GET['ad_id'];
4457 $amount = classifieds_ad_payment_amount( $ad_id );
4458 if( !empty( $amount ) ){
4459
4460 $store_contact_email = $store->store_contact_email;
4461
4462 $mollie_id = classifieds_get_option( 'mollie_id' );
4463 $iDEAL = new Mollie_iDEAL_Payment( $mollie_id );
4464 $ideal_mode = classifieds_get_option( 'ideal_mode' );
4465 if( $ideal_mode == 'test' ){
4466 $iDEAL->setTestmode(true);
4467 }
4468 $iDEAL->checkPayment($_GET['transaction_id']);
4469
4470 if ( $iDEAL->getPaidStatus() ){
4471 classifieds_mark_store_as_paid( $ad_id );
4472 }
4473 }
4474 }
4475}
4476
4477/*
4478Return message for the Skrill confirmation
4479*/
4480function classifieds_pay_with_skrill(){
4481 return '<div class="alert alert-success clearfix">'.esc_html__( 'Once Skrill confirms payment ad will be added to review proces. After it you will receive information about it.', 'classifieds' ).'</div>';
4482}
4483
4484/*
4485Inform user once Skrill returns result
4486*/
4487function classifieds_skrill_payment_confirmation(){
4488 if( isset( $_GET['ad_id'] ) ){
4489 global $wpdb;
4490 $store_id = $_GET['ad_id'];
4491 $amount = classifieds_ad_payment_amount( $ad_id );
4492 if( !empty( $amount ) ){
4493 if( isset( $_POST['merchant_id'] ) ){
4494 $skrill_secret_word = classifieds_get_option( 'skrill_secret_word' );
4495 $concatFields = $_POST['merchant_id']
4496 .$_POST['transaction_id']
4497 .strtoupper(md5($skrill_secret_word))
4498 .$_POST['mb_amount']
4499 .$_POST['mb_currency']
4500 .$_POST['status'];
4501
4502 $MBEmail = classifieds_get_option( 'skrill_owner_mail' );
4503
4504 if ( strtoupper( md5($concatFields) ) == $_POST['md5sig'] && $_POST['status'] == 2 && $_POST['pay_to_email'] == $MBEmail ){
4505 classifieds_mark_store_as_paid( $ad_id );
4506 }
4507 }
4508 }
4509 }
4510}
4511
4512/*
4513Return message for the Bank Transfer
4514*/
4515function classifieds_pay_with_bank(){
4516 $bank_account_name = classifieds_get_option( 'bank_account_name' );
4517 $bank_name = classifieds_get_option( 'bank_name' );
4518 $bank_account_number = classifieds_get_option( 'bank_account_number' );
4519 $bank_sort_number = classifieds_get_option( 'bank_sort_number' );
4520 $bank_iban_number = classifieds_get_option( 'bank_iban_number' );
4521 $bank_bic_swift_number = classifieds_get_option( 'bank_bic_swift_number' );
4522 return '<div class="white-block">
4523 <div class="white-block-content">
4524 '.esc_html__( 'Make your payment directly into our bank account. Please use ad title as the payment reference. Your order won’t be processed until the funds have cleared in our account.', 'classifieds' ).'
4525 <h4>'.esc_html__( 'Our Bank Details', 'classifieds' ).'</h4>
4526 '.$bank_account_name.' - '.$bank_name.'
4527 <ul class="list-unstyled list=inline">
4528 <li>
4529 '.esc_html__( 'ACCOUNT NUMBER', 'classifieds' ).':
4530 '.$bank_account_number.'
4531 </li>
4532 <li>
4533 '.esc_html__( 'SORT CODE', 'classifieds' ).':
4534 '.$bank_sort_number.'
4535 </li>
4536 <li>
4537 '.esc_html__( 'IBAN', 'classifieds' ).':
4538 '.$bank_iban_number.'
4539 </li>
4540 <li>
4541 '.esc_html__( 'BIC', 'classifieds' ).':
4542 '.$bank_bic_swift_number.'
4543 </li>
4544 </ul>
4545 </div>
4546 </div>';
4547}
4548
4549/*
4550Send mail notification to the user about review of the ad
4551*/
4552function classifieds_inform_user( $user_id, $message, $subject ){
4553 $name_sender = classifieds_get_option( 'name_sender' );
4554 $email_sender = classifieds_get_option( 'email_sender' );
4555 $user_mail = get_the_author_meta( 'user_email', $user_id );
4556
4557 $ad_messaging = classifieds_get_option( 'ad_messaging' );
4558 if( $ad_messaging == 'yes'){
4559 $headers = array();
4560 $headers[] = "MIME-Version: 1.0";
4561 $headers[] = "Content-Type: text/html; charset=UTF-8";
4562 $headers[] = "From: ".$name_sender." <".$email_sender.">";
4563
4564 $info = wp_mail( $user_mail, $subject, $message, $headers );
4565 }
4566}
4567
4568/*
4569Send email to admin about new ad being submitted
4570*/
4571function classifieds_inform_admin( $post_id, $is_expired = false ){
4572 $new_offer_email = classifieds_get_option( 'new_offer_email' );
4573 $name_sender = classifieds_get_option( 'name_sender' );
4574 $email_sender = classifieds_get_option( 'email_sender' );
4575
4576 $headers = array();
4577 $headers[] = "MIME-Version: 1.0";
4578 $headers[] = "Content-Type: text/html; charset=UTF-8";
4579 $headers[] = "From: ".$name_sender." <".$email_sender.">";
4580
4581 if( $is_expired ){
4582 $message = esc_html__( 'Ad submited for renewal.', 'classifieds' );
4583 $subject = esc_html__( 'Ad Renewal Submited', 'classifieds' );
4584 delete_post_meta( $post_id, 'ad_expire_mark' );
4585 }
4586 else{
4587 $message = esc_html__( 'New ad has been submited.', 'classifieds' );
4588 $subject = esc_html__( 'New Ad Submited', 'classifieds' );
4589 }
4590 $message .= '<br/><br/>';
4591 $message .= esc_html__( 'You can access it on the following link: ', 'classifieds' ).admin_url( 'post.php?post='.$post_id.'&action=edit' );
4592
4593 $info = wp_mail( $new_offer_email, '['.get_bloginfo( 'name' ).'] '.$subject, $message, $headers );
4594}
4595
4596/*
4597Increment number of views for the ad single
4598*/
4599function classifieds_increment_views( $post_id ){
4600 $views = get_post_meta( $post_id, 'ad_views', true );
4601 if( empty( $views ) ){
4602 $views = 0;
4603 }
4604
4605 $views++;
4606
4607 update_post_meta( $post_id, 'ad_views', $views );
4608}
4609
4610/*
4611Dispaly number of views
4612*/
4613function classifieds_ad_views(){
4614 $ad_views = get_post_meta( get_the_ID(), 'ad_views', true );
4615 if( empty( $ad_views ) ){
4616 $ad_views = 0;
4617 }
4618 if( $ad_views >= 1000 ){
4619 $ad_views = round( $ad_views / 100, 1 ).'k';
4620 }
4621
4622 echo $ad_views;
4623}
4624
4625/*
4626Get organized list of custom taxonomy in form parent->child
4627for the front end listing
4628*/
4629function classifieds_get_organized( $taxonomy ){
4630 $categories = get_terms( $taxonomy, array('hide_empty' => false));
4631 $taxonomy_organized = array();
4632 classifieds_sort_terms_hierarchicaly($categories, $taxonomy_organized);
4633 $taxonomy_organized = (array) $taxonomy_organized;
4634
4635 $sortby = classifieds_get_option( 'all_categories_sortby' );
4636 $sort = classifieds_get_option( 'all_categories_sort' );
4637
4638
4639 if( $sort == 'asc' ){
4640 switch( $sortby ){
4641 case 'name' : usort( $taxonomy_organized, "classifieds_organized_sort_name_asc" ); break;
4642 case 'slug' : usort( $taxonomy_organized, "classifieds_organized_sort_slug_asc" ); break;
4643 case 'count' : usort( $taxonomy_organized, "classifieds_organized_sort_count_asc" ); break;
4644 default : usort( $taxonomy_organized, "classifieds_organized_sort_name_asc" ); break;
4645 }
4646
4647 }
4648 else{
4649 switch( $sortby ){
4650 case 'name' : usort( $taxonomy_organized, "classifieds_organized_sort_name_desc" ); break;
4651 case 'slug' : usort( $taxonomy_organized, "classifieds_organized_sort_slug_desc" ); break;
4652 case 'count' : usort( $taxonomy_organized, "classifieds_organized_sort_count_desc" ); break;
4653 default : usort( $taxonomy_organized, "classifieds_organized_sort_name_desc" ); break;
4654 }
4655 }
4656 return $taxonomy_organized;
4657
4658}
4659
4660/*
4661Sort taxonomy terms by name ASC
4662*/
4663function classifieds_organized_sort_name_asc( $a, $b ){
4664 return strcmp( $a->name, $b->name );
4665}
4666
4667/*
4668Sort taxonomy terms by name DESC
4669*/
4670function classifieds_organized_sort_name_desc( $a, $b ){
4671 return strcmp( $b->name, $a->name );
4672}
4673
4674/*
4675Sort taxonomy terms by slug ASC
4676*/
4677function classifieds_organized_sort_slug_asc( $a, $b ){
4678 return strcmp( $a->slug, $b->slug );
4679}
4680
4681/*
4682Sort taxonomy terms by slug DESC
4683*/
4684function classifieds_organized_sort_slug_desc( $a, $b ){
4685 return strcmp( $b->slug, $a->slug );
4686}
4687
4688/*
4689Sort taxonomy terms by count ASC
4690*/
4691function classifieds_organized_sort_count_asc( $a, $b ){
4692 return strcmp( $a->count, $b->count );
4693}
4694
4695/*
4696Sort taxonomy terms by count DESC
4697*/
4698function classifieds_organized_sort_count_desc( $a, $b ){
4699 return strcmp( $b->count, $a->count );
4700}
4701
4702
4703/*
4704Display custom taxonomy on their listing pages
4705All Categories, All Brands
4706*/
4707function classifieds_display_tree( $cat, $taxonomy, $all_categories_count = 'no' ){
4708 $list = array();
4709 foreach( $cat->children as $key => $child ){
4710 $list[] = '<a href="'.esc_url( add_query_arg( array( $taxonomy => $child->slug ), classifieds_get_permalink_by_tpl( 'page-tpl_search_page' ) ) ).'">'.$child->name.' '.( $all_categories_count == 'yes' ? '('.classifieds_category_count( $child->slug ).')' : '' ).'</a>';
4711 if( !empty( $child->children ) ){
4712 $list = array_merge( $list, classifieds_display_tree( $child, $taxonomy, $all_categories_count ) );
4713 }
4714 }
4715
4716 return $list;
4717}
4718
4719/*
4720Custom products per page
4721*/
4722function classifieds_products_per_page(){
4723 return classifieds_get_option( 'products_per_page' );
4724}
4725add_filter( 'loop_shop_per_page', 'classifieds_products_per_page', 20 );
4726
4727/*
4728Get page top parent
4729*/
4730function classifieds_top_parent( $parent_id ){
4731 $page = get_post( $parent_id );
4732 $parent_id = $page->post_parent;
4733 if( $parent_id > 0 ){
4734 $parent_id = classifieds_top_parent( $parent_id );
4735 }
4736 else{
4737 $parent_id = $page->ID;
4738 }
4739
4740 return $parent_id;
4741}
4742
4743/*
4744Generate side menu for the side menu template
4745*/
4746function classifieds_generate_side_menu(){
4747 $page_id = get_the_ID();
4748 $parent_id = classifieds_top_parent( $page_id );
4749 wp_list_pages(array(
4750 'child_of' => $parent_id,
4751 'title_li' => false,
4752 'sort_column' => 'menu_order',
4753 'sort_order' => 'DESC'
4754 ));
4755}
4756
4757/*
4758Convert nbsp to p with class
4759*/
4760function classifieds_nbsp_to_class( $content ){
4761 $content = str_replace( '<p> </p>' , '<p class="pspace"> </p>', $content);
4762 return $content;
4763}
4764add_filter( 'the_content', 'classifieds_nbsp_to_class' );
4765
4766
4767/*
4768Send expire notice to author
4769*/
4770function classifieds_send_expire_notice(){
4771 $send_expire_notice = classifieds_get_option('send_expire_notice');
4772 $last_check = get_option( 'classifieds_expire_check' );
4773 if( $send_expire_notice == 'yes' ){
4774 if( ( current_time( 'timestamp' ) - $last_check ) >= 86400 ){
4775 global $wpdb;
4776 delete_transient( 'classifieds_expire_reminder_data' );
4777 $data = array();
4778 $has_data = true;
4779 $counter = 1;
4780 while( $has_data ){
4781 $offset = ( $counter - 1 ) * 500;
4782 $counter++;
4783 $results = $wpdb->get_results(
4784 $wpdb->prepare(
4785 "SELECT posts.ID AS post_id, user_login, user_email, post_title FROM {$wpdb->posts} AS posts
4786 LEFT JOIN {$wpdb->postmeta} AS postmeta1 ON (posts.ID = postmeta1.post_id AND postmeta1.meta_key = 'ad_expire_mark' )
4787 LEFT JOIN {$wpdb->postmeta} AS postmeta2 ON posts.ID = postmeta2.post_id
4788 LEFT JOIN {$wpdb->users} AS users ON posts.post_author = users.ID
4789 WHERE 1=1
4790 AND ( postmeta1.post_id IS NULL AND ( postmeta2.meta_key = 'ad_expire' AND CAST(postmeta2.meta_value AS CHAR) < %s ) )
4791 AND posts.post_type = 'ad' AND posts.post_status = 'publish'
4792 GROUP BY posts.ID LIMIT 500 OFFSET %d",
4793 current_time( 'timestamp' ),
4794 $offset
4795 )
4796 );
4797 if( !empty( $results ) ){
4798 foreach( $results AS $result ){
4799 $data[] = array(
4800 'user_login' => $result->user_login,
4801 'user_email' => $result->user_email,
4802 'post_title' => $result->post_title,
4803 'ID' => $result->post_id,
4804 );
4805 }
4806 }
4807 else{
4808 $has_data = false;
4809 }
4810 }
4811
4812 set_transient( 'classifieds_expire_reminder_data', json_encode( $data ), 60*60*24 );
4813 update_option( 'classifieds_expire_check', current_time( 'timestamp' ) );
4814
4815 }
4816 else{
4817 $data = json_decode( get_transient( 'classifieds_expire_reminder_data' ), true );
4818 }
4819
4820 if( !empty( $data ) ){
4821 $email_sender = classifieds_get_option( 'email_sender' );
4822 $name_sender = classifieds_get_option( 'name_sender' );
4823 $expire_template = classifieds_get_option('expire_template');
4824 $ad_expire_subject = classifieds_get_option( 'ad_expire_subject' );
4825 $headers = array();
4826 $headers[] = "MIME-Version: 1.0";
4827 $headers[] = "Content-Type: text/html; charset=UTF-8";
4828 $headers[] = "From: ".$name_sender." <".$email_sender.">";
4829
4830 while( !empty( $data ) ){
4831 $item = array_shift( $data );
4832 $message = str_replace( '%USERNAME%', $item['user_login'], $expire_template );
4833 $message = str_replace( '%AD_NAME%', $item['post_title'], $message );
4834 $info = wp_mail( $item['user_email'], $ad_expire_subject, $message, $headers );
4835 if( $info ){
4836 update_post_meta( $item['ID'], 'ad_expire_mark', '1' );
4837 set_transient( 'classifieds_expire_reminder_data', json_encode( $data ), 60*60*24 );
4838 }
4839 }
4840 }
4841 }
4842}
4843add_action( 'init', 'classifieds_send_expire_notice' );
4844
4845/*
4846Allow SVG file format
4847*/
4848function classifieds_mime_types($mimes){
4849 $mimes['svg'] = 'image/svg+xml';
4850 return $mimes;
4851}
4852add_filter('upload_mimes', 'classifieds_mime_types');
4853
4854/*
4855Add clear cache link to admin bar
4856*/
4857function classifieds_admin_bar_clear_cache( $wp_admin_bar ) {
4858 $args = array(
4859 'id' => 'classifieds_clear_cache',
4860 'title' => esc_html__( 'Clear Map Cache', 'classifieds' ),
4861 'href' => 'javascript:;',
4862 'meta' => array( 'class' => 'classifieds_clear_cache' )
4863 );
4864 $wp_admin_bar->add_node( $args );
4865}
4866add_action( 'admin_bar_menu', 'classifieds_admin_bar_clear_cache', 999 );
4867
4868/*
4869Clear cache
4870*/
4871function classifieds_clear_cache(){
4872 delete_transient( 'classifieds_home_markers' );
4873 die();
4874}
4875add_action('wp_ajax_classifieds_clear_cache', 'classifieds_clear_cache');
4876
4877
4878/*Clear single-ad for ad blocker*/
4879function classifieds_fix_class( $classes ){
4880 foreach( $classes as &$class ){
4881 if( $class == 'single-ad' ){
4882 $class = 'single-cad';
4883 }
4884 }
4885 return $classes;
4886}
4887add_filter('body_class', 'classifieds_fix_class');
4888
4889/* Organize custom fields by name so select box can be displayed easier */
4890function classifieds_organize_custom_fields( $custom_fields ){
4891 $organized = array();
4892 foreach( $custom_fields as $field ){
4893 if( $field->parent == '0' ){
4894 if( empty( $organized[$field->field_id] ) ){
4895 $organized[$field->field_id] = array(
4896 'field' => $field,
4897 'values' => array(),
4898 'children' => array()
4899 );
4900 }
4901
4902 $organized[$field->field_id]['field'] = $field;
4903 $organized[$field->field_id]['values'][] = $field->val;
4904
4905 }
4906 else{
4907 if( empty( $organized[$field->parent] ) ){
4908 $organized[$field->parent] = array(
4909 'children' => array()
4910 );
4911 }
4912
4913 $organized[$field->parent]['children'][$field->field_id]['field'] = $field;
4914 $organized[$field->parent]['children'][$field->field_id]['values'][] = $field->val;
4915 }
4916 }
4917
4918 return $organized;
4919}
4920
4921/*Strip special chars for the class*/
4922function classifieds_clean_class( $class ) {
4923 $class = str_replace(' ', '', $class);
4924 return preg_replace( '/[^A-Za-z0-9\-]/', '', $class );
4925}
4926
4927/* generate select filter for the frontend */
4928function classifieds_generate_filter_field( $field_data ){
4929 if( $field_data['field']->type == 'input' ){
4930 $values = join( '|', $field_data['values'] );
4931 $values = explode( '|', $values );
4932 }
4933 else{
4934 $values = explode( "\n", $field_data['field']->field_values );
4935 }
4936
4937 $conditional = '';
4938 if( $field_data['field']->parent !== '0' ){
4939 $temp = explode( '|', $field_data['field']->child_of_value );
4940 $conditional = 'conditional-hide '.classifieds_clean_class( $temp[0].'-'.$field_data['field']->parent );
4941 }
4942
4943 $html = '<select data-field-id = "'.esc_attr( $field_data['field']->field_id ).'" id="'.esc_attr( $field_data['field']->name ).'" name="'.esc_attr( $field_data['field']->name ).''.( $field_data['field']->type == 'input' ? '[]' : '' ).'" class="form-control filter-select '.( esc_attr( $conditional ) ).'" '.( $field_data['field']->type == 'input' ? 'multiple' : '' ).' data-placeholder="'.esc_attr__( 'Select', 'classifieds' ).'">';
4944 $html .= '<option value=""></option>';
4945 $added = array();
4946 if( !empty( $values ) ){
4947 foreach( $values as $val ){
4948 if( !empty( $val ) && !in_array( $val, $added ) ){
4949 $added[] = $val;
4950 if( $field_data['field']->type == 'input' ){
4951 $html .= '<option value="'.esc_attr( $val ).'">'.$val.'</option>';
4952 }
4953 else{
4954 $temp = explode( '|', $val );
4955 $html .= '<option value="'.esc_attr( $temp[0] ).'">'.$temp[1].'</option>';
4956 }
4957 }
4958 }
4959 }
4960 $html .= '</select>';
4961
4962 return $html;
4963}
4964
4965/* Generate list of filters based on the category selected on the search page */
4966function classifieds_custom_filter(){
4967 global $wpdb, $classifieds_slugs;
4968
4969 $cats = array();
4970
4971 $category = isset( $_GET[$classifieds_slugs['category']] ) ? $_GET[$classifieds_slugs['category']] : '';
4972 if( empty( $category ) ){
4973 $category = isset( $_POST['category'] ) ? $_POST['category'] : '';
4974 }
4975
4976 $html = '';
4977
4978 if( !empty( $category ) ){
4979
4980 $cat = get_term_by( 'slug', $category, 'ad-category' );
4981
4982 $post_id = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->postmeta} WHERE meta_key = 'fields_for' AND meta_value LIKE %s", '%\"'.$cat->slug.'\"%' ) );
4983 if( !empty( $post_id[0] ) ){
4984 $custom_fields = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}custom_fields AS cf LEFT JOIN {$wpdb->prefix}custom_fields_meta AS meta ON cf.name = meta.name WHERE cf.post_id = %d", $post_id[0]->post_id ) );
4985 if( !empty( $custom_fields ) ){
4986 $custom_fields = classifieds_organize_custom_fields( $custom_fields );
4987 $html .= '<h4>'.esc_html__( 'Filter', 'classifieds' ).' '.$cat->name.'</h4><form class="form-login filter-form"><ul class="list-unstyled">';
4988 foreach( $custom_fields as $field_data ){
4989 $html .= '
4990 <li>
4991 <label for="'.esc_attr__( $field_data['field']->name ).'">'.esc_attr__( $field_data['field']->label ).'</label>
4992 '.classifieds_generate_filter_field( $field_data ).'
4993 </li>';
4994
4995 if( !empty( $field_data['children'] ) ){
4996 foreach( $field_data['children'] as $field_child ){
4997 $html .= '
4998 <li class="hidden">
4999 <label for="'.esc_attr__( $field_child['field']->name ).'">'.esc_attr__( $field_child['field']->label ).'</label>
5000 '.classifieds_generate_filter_field( $field_child ).'
5001 </li>';
5002 }
5003 }
5004 }
5005 $html .= '</ul><a href="javascript:;" class="filter-results" data-dismiss="modal">'.esc_html__( 'Filter', 'classifieds' ).'</a></form>';
5006 }
5007 }
5008 }
5009
5010 echo $html;
5011 if( isset( $_POST['action'] ) ){
5012 die();
5013 }
5014}
5015add_action('wp_ajax_custom_filter', 'classifieds_custom_filter');
5016add_action('wp_ajax_nopriv_custom_filter', 'classifieds_custom_filter');
5017
5018/*
5019Get placeholder image
5020*/
5021global $classifieds_placeholder_image;
5022$classifieds_placeholder_image = '';
5023function classifieds_get_placeholder_image( $image_size ){
5024 global $classifieds_placeholder_image, $wpdb;;
5025 $image_placeholder = classifieds_get_option( 'image_placeholder' );
5026 if( !empty( $image_placeholder['url'] ) && empty( $classifieds_placeholder_image ) ){
5027 if( empty( $classifieds_placeholder_image ) ){
5028 $image_data = $wpdb->get_results( $wpdb->prepare( "SELECT ID FROM {$wpdb->posts} WHERE guid = %s", $image_placeholder['url'] ) );
5029 if( !empty( $image_data[0] ) ){
5030 $classifieds_placeholder_image = wp_get_attachment_image( $image_data[0]->ID, $image_size );
5031 }
5032 }
5033 }
5034
5035 echo $classifieds_placeholder_image;
5036}
5037
5038/*
5039Get category term count of ads
5040*/
5041if( !function_exists('classifieds_category_count') ){
5042function classifieds_category_count( $category ){
5043 $category_data = get_transient( 'classifieds_category_count_'.$category );
5044 if( !empty( $category_data ) ){
5045 $count = $category_data;
5046 }
5047 else{
5048 $posts = get_posts(array(
5049 'post_type' => 'ad',
5050 'posts_per_page' => '-1',
5051 'tax_query' => array(
5052 'relation' => 'AND',
5053 array(
5054 'taxonomy' => 'ad-category',
5055 'field' => 'slug',
5056 'terms' => $category,
5057 )
5058 ),
5059 'meta_query' => array(
5060 array(
5061 'key' => 'ad_expire',
5062 'value' => current_time( 'timestamp' ),
5063 'compare' => '>='
5064 ),
5065 array(
5066 'key' => 'ad_visibility',
5067 'value' => 'yes',
5068 'compare' => '='
5069 )
5070 )
5071 ));
5072 $count = count( $posts );
5073 set_transient( 'classifieds_category_count_'.$category, $count, 60*60 );
5074 }
5075
5076 return $count;
5077}
5078}
5079
5080
5081require_once( classifieds_load_path( 'includes/class-tgm-plugin-activation.php' ) );
5082require_once( classifieds_load_path( 'includes/google-fonts.php' ) );
5083require_once( classifieds_load_path( 'includes/awesome-icons.php' ) );
5084require_once( classifieds_load_path( 'includes/ad-cat-meta.php' ) );
5085require_once( classifieds_load_path( 'includes/gallery.php' ) );
5086require_once( classifieds_load_path( 'includes/widgets.php' ) );
5087require_once( classifieds_load_path( 'includes/paypal.class.php' ) );
5088require_once( classifieds_load_path( 'includes/mollie.php' ) );
5089require_once( classifieds_load_path( 'includes/theme-options.php' ) );
5090require_once( classifieds_load_path( 'includes/menu-extender.php' ) );
5091require_once( classifieds_load_path( 'includes/custom-ad-fields.php' ) );
5092require_once( classifieds_load_path( 'includes/radium-one-click-demo-install/init.php' ) );
5093if( is_admin() ){
5094 require_once( classifieds_load_path( 'includes/shortcodes.php' ) );
5095}
5096foreach ( glob( get_template_directory().'/includes/shortcodes/*.php' ) as $filename ){
5097 require_once( classifieds_load_path( 'includes/shortcodes/'.basename( $filename ) ) );
5098}
5099add_filter('_wpc_set_user_profile_link', function($url, $user_id) {
5100
5101 $user = get_userdata( $user_id );
5102
5103 return home_url( '/author/' . $user->user_nicename . '/?post_type=ad' );
5104
5105}, 10, 2);
5106// Replace 'Direct Message' old link with fresh direct WpChats link to chat
5107add_action('wp_footer', function() {
5108 ?>
5109 <script type="text/javascript">
5110 /**
5111 * Replace 'Direct Message' old link with fresh direct WpChats link to chat
5112 * @author Samuel Elh
5113 */
5114 window.onload = function() {
5115 var b = document.body,
5116 c = b['classList'];
5117 for (var i=0;i<c.length;i++) {
5118 if( null !== c[i].match(/\d+/) && 'author' == c[i].replace('-'+c[i].match(/\d+/), '') ) {
5119 var u = c[i].match(/\d+/),
5120 r = '<?php echo home_url( '/messages/?recipient=[x]' ); ?>',
5121 li = document.querySelectorAll('body.archive .list-unstyled > li');
5122 r = r.replace('[x]', u);
5123 for (var i=0;i<li.length;i++) {
5124 if('directmessage' == li[i].innerText.toLowerCase().replace(/ /g, '')) {
5125 li[i].querySelector('a').href = r;
5126 }
5127 };
5128 }
5129 };
5130 }
5131 </script>
5132 <?php
5133});
5134?>