Advertisement
Guest User

Untitled

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