<?php
require_once(__DIR__."/../db/connection.php");

if(!isset($_SESSION['timezone'])) {
    $settings = get_settings();
    if(!empty($settings['timezone'])) {
        date_default_timezone_set($settings['timezone']);
        $_SESSION['timezone']=$settings['timezone'];
    }
} else {
    if(!empty($_SESSION['timezone'])) date_default_timezone_set($_SESSION['timezone']);
}

function set_language($language,$domain) {
    if (session_status() === PHP_SESSION_NONE) {
        session_start();
    }
    if (function_exists('gettext')) {
        if(!isset($_SESSION['lang']) || $_SESSION['lang']=='') {
            $_SESSION['lang']=$language;
        } else {
            $language=$_SESSION['lang'];
        }
        if(defined('LC_MESSAGES')) {
            $result = setlocale(LC_MESSAGES, $language);
            if(!$result) {
                setlocale(LC_MESSAGES, $language.'.UTF-8');
            }
            if (function_exists('putenv')) {
                $result = putenv('LC_MESSAGES='.$language);
                if(!$result) {
                    putenv('LC_MESSAGES='.$language.'.UTF-8');
                }
            }
        } else {
            if (function_exists('putenv')) {
                $result = putenv('LC_ALL=' . $language);
                if (!$result) {
                    putenv('LC_ALL=' . $language . '.UTF-8');
                }
            }
        }
        if(!file_exists("../locale/".$language."/LC_MESSAGES/custom.mo")) {
            $domain = "default";
        }
        $result = bindtextdomain($domain, "../locale");
        if(!$result) {
            $domain = "default";
            bindtextdomain($domain, "../locale");
        }
        bind_textdomain_codeset($domain, 'UTF-8');
        textdomain($domain);
        if (!function_exists('_')) {
            function _($a) {
                return gettext($a);
            }
        }
    } else {
        if (!function_exists('_')) {
            function _($a) {
                return $a;
            }
        }
    }
}

function detectUserLanguage() {
    $settings = get_settings();
    if (!isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
        return '';
    }
    $accepted_languages = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']);
    foreach ($accepted_languages as $lang) {
        $lang = explode(';', $lang)[0];
        $lang = str_replace('-','_',$lang);
        if (check_language_enabled($lang,$settings['languages_enabled'])) {
            return $lang;
        }
        $lang_prefix = substr($lang, 0, 2);
        foreach ($settings['languages_enabled'] as $key => $value) {
            if($value==1) {
                if (strpos($key, $lang_prefix) === 0) {
                    return $key;
                }
            }
        }
    }
    return '';
}

function is_ssl() {
    if ( isset( $_SERVER['HTTPS'] ) ) {
        if ( 'on' == strtolower( $_SERVER['HTTPS'] ) ) {
            return true;
        }
        if ( '1' == $_SERVER['HTTPS'] ) {
            return true;
        }
    } elseif ( isset( $_SERVER['SERVER_PORT'] ) && ( '443' == $_SERVER['SERVER_PORT'] ) ) {
        return true;
    }
    return false;
}

function get_user_info($id_user) {
    global $mysqli;
    $return = array();
    $query = "SELECT * FROM sml_users WHERE id=? LIMIT 1;";
    if($smt = $mysqli->prepare($query)) {
        $smt->bind_param('i',$id_user);
        $result = $smt->execute();
        if($result) {
            $result = get_result($smt);
            if(count($result)==1) {
                $row = array_shift($result);
                $return=$row;
            }
        }
    }
    return $return;
}

function get_user_role($id_user) {
    global $mysqli;
    $return = array();
    $query = "SELECT * FROM sml_users WHERE id=? LIMIT 1;";
    if($smt = $mysqli->prepare($query)) {
        $smt->bind_param('i',$id_user);
        $result = $smt->execute();
        if($result) {
            $result = get_result($smt);
            if(count($result)==1) {
                $row = array_shift($result);
                $return=$row['role'];
            }
        }
    }
    return $return;
}

function get_settings() {
    global $mysqli,$language,$settings,$_SESSION;
    if(!isset($language) && isset($_SESSION['lang'])) $language=$_SESSION['lang'];
    if(isset($settings)) {
        if(isset($settings['version'])) {
            return $settings;
        }
    }
    $return = array();
    $query = "SELECT * FROM sml_settings LIMIT 1;";
    if($smt = $mysqli->prepare($query)) {
        $result = $smt->execute();
        if($result) {
            $result = get_result($smt);
            if(count($result)==1) {
                $row = array_shift($result);
                if(empty($row['languages_enabled'])) {
                    $row['languages_enabled']=array();
                    $row['languages_enabled']['en_US']=1;
                } else {
                    $row['languages_enabled']=json_decode($row['languages_enabled'],true);
                }
                $row['languages_count']=0;
                foreach ($row['languages_enabled'] as $lang) {
                    if($lang==1) {
                        $row['languages_count']++;
                    }
                }
                if($row['languages_count']==0) {
                    $row['languages_enabled']=array();
                    $row['languages_enabled']['en_US']=1;
                    $row['languages_count']=1;
                }
                if(!isset($row['style_login'])) {
                    $row['style_login']=1;
                }
                if(!isset($row['dark_mode'])) {
                    $row['dark_mode']=0;
                }
                $return=$row;
            }
        }
    }
    return $return;
}

function get_languages_backend() {
    global $settings;
    $count_languages_enabled = 0;
    foreach ($settings['languages_enabled'] as $lang_enabled) {
        if($lang_enabled==1) {
            $count_languages_enabled++;
        }
    }
    $default_language = $settings['language'];
    if($count_languages_enabled>0) {
        if(array_key_exists($default_language,$settings['languages_enabled'])) {
            $settings['languages_enabled'][$default_language]=1;
        }
    }
    $array_languages = array();
    foreach ($settings['languages_enabled'] as $lang=>$enabled) {
        if($enabled==1) {
            array_push($array_languages,$lang);
        }
    }
    return [$array_languages,$default_language];
}

function get_languages_map() {
    global $map,$settings;
    $count_languages_enabled = 0;
    foreach ($map['languages_enabled'] as $lang_enabled) {
        if($lang_enabled==1) {
            $count_languages_enabled++;
        }
    }
    $default_language = $map['language'];
    if(empty($default_language)) {
        $default_language = $settings['language'];
    }
    if($count_languages_enabled>0) {
        if(array_key_exists($default_language,$map['languages_enabled'])) {
            $map['languages_enabled'][$default_language]=1;
        }
    }
    $array_languages = array();
    foreach ($map['languages_enabled'] as $lang=>$enabled) {
        if($enabled==1) {
            array_push($array_languages,$lang);
        }
    }
    return [$array_languages,$default_language];
}

function check_language_enabled($lang,$languages_enabled) {
    if(empty($languages_enabled) && $lang=='en_US') {
        return true;
    } else if(empty($languages_enabled[$lang])) {
        return false;
    } else if($languages_enabled[$lang]==1) {
        return true;
    } else {
        return false;
    }
}

function check_language_enabled_map($lang,$languages_enabled,$languages_enabled_map) {
    if(empty($languages_enabled)) {
        if($languages_enabled_map[$lang]==1) {
            return true;
        } else {
            return false;
        }
    } else if(empty($languages_enabled_map[$lang])) {
        return false;
    } else if($languages_enabled_map[$lang]==1) {
        return true;
    } else {
        return false;
    }
}

function get_map($id_map,$id_user) {
    global $mysqli;
    $return = array();
    $query = "SELECT m.*,i.image as markers_icon_image,i2.image as pin_marker_icon_image FROM sml_maps as m 
                LEFT JOIN sml_icons as i ON i.id=m.markers_id_icon_library
                LEFT JOIN sml_icons as i2 ON i2.id=m.pin_marker_id_icon_library
                WHERE m.id=? LIMIT 1;";
    if($smt = $mysqli->prepare($query)) {
        $smt->bind_param('i',$id_map);
        $result = $smt->execute();
        if($result) {
            $result = get_result($smt);
            if(count($result)==1) {
                $row = array_shift($result);
                $id_user_m = $row['id_user'];
                switch(get_user_role($id_user)) {
                    case 'customer':
                        if($id_user!=$id_user_m) return false;
                        break;
                }
                $row['markers_icon'] = explode("|",$row['markers_icon'])[0];
                $row['pin_marker_icon'] = explode("|",$row['pin_marker_icon'])[0];
                $row['info_icon'] = explode("|",$row['info_icon'])[0];
                if(empty($row['markers_icon_image'])) $row['markers_icon_image']='';
                if(empty($row['pin_marker_icon_image'])) $row['pin_marker_icon_image']='';
                if(empty($row['languages_enabled'])) {
                    $row['languages_enabled']=array();
                } else {
                    $row['languages_enabled']=json_decode($row['languages_enabled'],true);
                }
                $return=$row;
            }
        }
    }
    return $return;
}

function get_category($id_category) {
    global $mysqli;
    $return = array();
    $query = "SELECT c.*,i.image as markers_icon_image,i2.image as icon_image FROM sml_categories as c 
           LEFT JOIN sml_icons as i ON i.id=c.markers_id_icon_library
           LEFT JOIN sml_icons as i2 ON i2.id=c.id_icon_library
           WHERE c.id=? LIMIT 1;";
    if($smt = $mysqli->prepare($query)) {
        $smt->bind_param('i',$id_category);
        $result = $smt->execute();
        if($result) {
            $result = get_result($smt);
            if(count($result)==1) {
                $row = array_shift($result);
                $row['markers_icon'] = explode("|",$row['markers_icon'])[0];
                if(empty($row['markers_icon_image'])) $row['markers_icon_image']='';
                $row['icon'] = explode("|",$row['icon'])[0];
                if(empty($row['icon_image'])) $row['icon_image']='';
                $return=$row;
            }
        }
    }
    return $return;
}

function get_marker_count_category($id_category) {
    global $mysqli;
    $return = 0;
    $query = "SELECT COUNT(*) as num FROM sml_markers_categories_assoc WHERE id_category=?;";
    if($smt = $mysqli->prepare($query)) {
        $smt->bind_param('i',$id_category);
        $result = $smt->execute();
        if($result) {
            $result = get_result($smt);
            if(count($result)==1) {
                $row = array_shift($result);
                $return = $row['num'];
            }
        }
    }
    return $return;
}

function get_marker_count_map($id_map) {
    global $mysqli;
    $return = 0;
    $query = "SELECT COUNT(*) as num FROM sml_markers WHERE id_map=?;";
    if($smt = $mysqli->prepare($query)) {
        $smt->bind_param('i',$id_map);
        $result = $smt->execute();
        if($result) {
            $result = get_result($smt);
            if(count($result)==1) {
                $row = array_shift($result);
                $return = $row['num'];
            }
        }
    }
    return $return;
}

function get_array_coordinates($id_map) {
    global $mysqli;
    $return = array();
    $query = "SELECT lat,lon FROM sml_markers WHERE (lat IS NOT NULL AND lat != '') AND (lon IS NOT NULL AND lon != '') AND id_map=?;";
    if($smt = $mysqli->prepare($query)) {
        $smt->bind_param('i',$id_map);
        $result = $smt->execute();
        if($result) {
            $result = get_result($smt);
            if(count($result)>0) {
                while($row = array_shift($result)) {
                    if(is_numeric($row['lat']) && is_numeric($row['lon'])) {
                        array_push($return,array($row['lat'],$row['lon']));
                    }
                }
            }
        }
    }
    return $return;
}

function get_markers_to_validate($id_user) {
    global $mysqli;
    $return = array();
    $where = "";
    $role = get_user_role($id_user);
    switch($role) {
        case 'administrator':
            $where = " WHERE 1=1 ";
            break;
        case 'customer':
            $where = " WHERE 1=1 AND id_user=? ";
            break;
        case 'editor':
            $where = " WHERE 1=1 AND id IN (0) ";
            $query = "SELECT GROUP_CONCAT(id_map) as ids FROM sml_assign_maps WHERE id_user=$id_user;";
            $result = $mysqli->query($query);
            if($result) {
                if($result->num_rows==1) {
                    $row=$result->fetch_array(MYSQLI_ASSOC);
                    $ids = $row['ids'];
                    if(!empty($ids)) {
                        $where = " WHERE 1=1 AND id IN ($ids) ";
                    }
                }
            }
            break;
    }
    $return = 0;
    $query = "SELECT COUNT(*) as num FROM sml_markers WHERE active=1 AND to_validate=1 AND id_map IN (SELECT id FROM sml_maps $where)";
    if($smt = $mysqli->prepare($query)) {
        if($role=='customer') {
            $smt->bind_param('i',$id_user);
        }
        $result = $smt->execute();
        if($result) {
            $result = get_result($smt);
            if(count($result)>0) {
                $row = array_shift($result);
                $return=$row['num'];
            }
        }
    }
    return $return;
}

function get_photos_to_validate($id_user,$id_marker=0) {
    global $mysqli;
    $return = array();
    $where = "";
    $role = get_user_role($id_user);
    switch($role) {
        case 'administrator':
            $where = " WHERE 1=1 ";
            break;
        case 'customer':
            $where = " WHERE 1=1 AND id_user=? ";
            break;
        case 'editor':
            $where = " WHERE 1=1 AND id IN (0) ";
            $query = "SELECT GROUP_CONCAT(id_map) as ids FROM sml_assign_maps WHERE id_user=$id_user;";
            $result = $mysqli->query($query);
            if($result) {
                if($result->num_rows==1) {
                    $row=$result->fetch_array(MYSQLI_ASSOC);
                    $ids = $row['ids'];
                    if(!empty($ids)) {
                        $where = " WHERE 1=1 AND id IN ($ids) ";
                    }
                }
            }
            break;
    }
    $return = 0;
    if($id_marker!=0) {
        $query = "SELECT COUNT(*) as num FROM sml_markers as m JOIN sml_images as i ON m.id=i.id_marker WHERE m.id=$id_marker AND i.to_validate=1 AND m.id_map IN (SELECT id FROM sml_maps $where)";
    } else {
        $query = "SELECT COUNT(*) as num FROM sml_markers as m JOIN sml_images as i ON m.id=i.id_marker WHERE m.active=1 AND i.to_validate=1 AND m.id_map IN (SELECT id FROM sml_maps $where)";
    }
    if($smt = $mysqli->prepare($query)) {
        if($role=='customer') {
            $smt->bind_param('i',$id_user);
        }
        $result = $smt->execute();
        if($result) {
            $result = get_result($smt);
            if(count($result)>0) {
                $row = array_shift($result);
                $return=$row['num'];
            }
        }
    }
    return $return;
}

function get_issue_reports_to_check($id_user) {
    global $mysqli;
    $return = array();
    $where = "";
    $role = get_user_role($id_user);
    switch($role) {
        case 'administrator':
            $where = " WHERE 1=1 ";
            break;
        case 'customer':
            $where = " WHERE 1=1 AND id_user=? ";
            break;
        case 'editor':
            $where = " WHERE 1=1 AND id IN (0) ";
            $query = "SELECT GROUP_CONCAT(id_map) as ids FROM sml_assign_maps WHERE id_user=$id_user;";
            $result = $mysqli->query($query);
            if($result) {
                if($result->num_rows==1) {
                    $row=$result->fetch_array(MYSQLI_ASSOC);
                    $ids = $row['ids'];
                    if(!empty($ids)) {
                        $where = " WHERE 1=1 AND id IN ($ids) ";
                    }
                }
            }
            break;
    }
    $return = 0;
    $query = "SELECT COUNT(*) as num FROM sml_issue_reports WHERE checked=0 AND id_marker IN (SELECT id FROM sml_markers WHERE id_map IN (SELECT id FROM sml_maps $where))";
    if($smt = $mysqli->prepare($query)) {
        if($role=='customer') {
            $smt->bind_param('i',$id_user);
        }
        $result = $smt->execute();
        if($result) {
            $result = get_result($smt);
            if(count($result)>0) {
                $row = array_shift($result);
                $return=$row['num'];
            }
        }
    }
    return $return;
}

function get_maps($id_user,$check="no") {
    global $mysqli;
    $return = array();
    $where = "";
    $role = get_user_role($id_user);
    switch($role) {
        case 'administrator':
            $where = " WHERE 1=1 ";
            break;
        case 'customer':
            $where = " WHERE 1=1 AND m.id_user=$id_user ";
            break;
        case 'editor':
            $where = " WHERE 1=1 AND m.id IN (0) ";
            $query = "SELECT GROUP_CONCAT(id_map) as ids FROM sml_assign_maps WHERE id_user=$id_user;";
            $result = $mysqli->query($query);
            if($result) {
                if($result->num_rows==1) {
                    $row=$result->fetch_array(MYSQLI_ASSOC);
                    $ids = $row['ids'];
                    if(!empty($ids)) {
                        $where = " WHERE 1=1 AND m.id IN ($ids) ";
                    }
                }
            }
            break;
    }
    switch($check) {
        case 'icons_library':
            $query = "SELECT m.id,m.id_user,m.code,m.name,
                         COUNT(DISTINCT i.id) AS count_check
                  FROM sml_maps AS m
                  LEFT JOIN sml_icons AS i ON i.id_map=m.id
                  $where
                  GROUP BY m.id,m.id_user,m.code,m.name,m.date_created
                  ORDER BY m.date_created DESC, m.id DESC;";
            break;
        case 'media_library':
            $query = "SELECT m.id,m.id_user,m.code,m.name,
                         COUNT(DISTINCT i.id) AS count_check
                  FROM sml_maps AS m
                  LEFT JOIN sml_media_library AS i ON i.id_map=m.id
                  $where
                  GROUP BY m.id,m.id_user,m.code,m.name,m.date_created
                  ORDER BY m.date_created DESC, m.id DESC;";
            break;
        case 'markers':
            $query = "SELECT m.id,m.id_user,m.code,m.name,
                         COUNT(DISTINCT mk.id) AS count_check
                  FROM sml_maps AS m
                  LEFT JOIN sml_markers AS mk ON mk.id_map=m.id
                  $where
                  GROUP BY m.id,m.id_user,m.code,m.name,m.date_created
                  ORDER BY m.date_created DESC, m.id DESC;";
            break;
        case 'markers_connections':
            $query = "SELECT m.id,m.id_user,m.code,m.name,
                         COUNT(DISTINCT i.id) AS count_check
                  FROM sml_maps AS m
                  LEFT JOIN sml_markers AS mk ON mk.id_map=m.id
                  LEFT JOIN sml_markers_connects AS i ON i.id_marker_source=mk.id OR i.id_marker_dest=mk.id
                  $where
                  GROUP BY m.id,m.id_user,m.code,m.name,m.date_created
                  ORDER BY m.date_created DESC, m.id DESC;";
            break;
        case 'story':
            $query = "SELECT m.id,m.id_user,m.code,m.name,
                         COUNT(DISTINCT s.id) AS count_check
                  FROM sml_maps AS m
                  LEFT JOIN sml_story AS s ON s.id_map=m.id
                  $where
                  GROUP BY m.id,m.id_user,m.code,m.name,m.date_created
                  ORDER BY m.date_created DESC, m.id DESC;";
            break;
        case 'categories':
            $query = "SELECT m.id,m.id_user,m.code,m.name,
                         COUNT(DISTINCT c.id) AS count_check
                  FROM sml_maps AS m
                  LEFT JOIN sml_categories AS c ON c.id_map=m.id
                  $where
                  GROUP BY m.id,m.id_user,m.code,m.name,m.date_created
                  ORDER BY m.date_created DESC, m.id DESC;";
            break;
        case 'reviews':
            $query = "SELECT m.id,m.id_user,m.code,m.name,
                         COUNT(DISTINCT r.id) AS count_check
                  FROM sml_maps AS m
                  LEFT JOIN sml_markers AS mk ON mk.id_map=m.id
                  LEFT JOIN sml_reviews AS r ON r.id_marker=mk.id
                  $where
                  GROUP BY m.id,m.id_user,m.code,m.name,m.date_created
                  ORDER BY m.date_created DESC, m.id DESC;";
            break;
        case 'issue_reports':
            $query = "SELECT m.id,m.id_user,m.code,m.name,
                         COUNT(DISTINCT r.id) AS count_check
                  FROM sml_maps AS m
                  LEFT JOIN sml_markers AS mk ON mk.id_map=m.id
                  LEFT JOIN sml_issue_reports AS r ON r.id_marker=mk.id
                  $where
                  GROUP BY m.id,m.id_user,m.code,m.name,m.date_created
                  ORDER BY m.date_created DESC, m.id DESC;";
            break;
        case 'markers_to_validate':
            $query = "SELECT m.id,m.id_user,m.code,m.name,
                         COUNT(DISTINCT mk.id) AS count_check
                  FROM sml_maps AS m
                  LEFT JOIN sml_markers AS mk ON mk.id_map=m.id AND mk.to_validate=1
                  $where 
                  GROUP BY m.id,m.id_user,m.code,m.name,m.date_created
                  ORDER BY m.date_created DESC, m.id DESC;";
            break;
        case 'photos_to_validate':
            $query = "SELECT m.id,m.id_user,m.code,m.name,
                         COUNT(DISTINCT i.id) AS count_check
                  FROM sml_maps AS m
                  LEFT JOIN sml_markers AS mk ON mk.id_map=m.id
                  LEFT JOIN sml_images as i ON i.id_marker=mk.id AND i.to_validate=1
                  $where 
                  GROUP BY m.id,m.id_user,m.code,m.name,m.date_created
                  ORDER BY m.date_created DESC, m.id DESC;";
            break;
        case 'live_tracking':
            $query = "SELECT m.id,m.id_user,m.code,m.name,
                         COUNT(DISTINCT l.id) AS count_check
                  FROM sml_maps AS m
                  LEFT JOIN sml_live_tracking_history AS l ON l.id_map=m.id
                  $where
                  GROUP BY m.id,m.id_user,m.code,m.name,m.date_created
                  ORDER BY m.date_created DESC, m.id DESC;";
            break;
        case 'geoimages':
            $query = "SELECT m.id,m.id_user,m.code,m.name,
                         COUNT(DISTINCT g.id) AS count_check
                  FROM sml_maps AS m
                  LEFT JOIN sml_geoimages AS g ON g.id_map=m.id
                  $where
                  GROUP BY m.id,m.id_user,m.code,m.name,m.date_created
                  ORDER BY m.date_created DESC, m.id DESC;";
            break;
        case 'boundaries':
            $query = "SELECT m.id,m.id_user,m.code,m.name,
                         IF(m.extent<>'',1,0) AS count_check
                  FROM sml_maps AS m
                  $where
                  GROUP BY m.id,m.id_user,m.code,m.name,m.date_created
                  ORDER BY m.date_created DESC, m.id DESC;";
            break;
        case 'geodata':
            $query = "SELECT m.id,m.id_user,m.code,m.name,
                         COUNT(DISTINCT g.id) AS count_check
                  FROM sml_maps AS m
                  LEFT JOIN sml_geodata AS g ON g.id_map=m.id
                  $where
                  GROUP BY m.id,m.id_user,m.code,m.name,m.date_created
                  ORDER BY m.date_created DESC, m.id DESC;";
            break;
        case 'bulk_translate':
            $query = "SELECT m.id,m.id_user,m.code,m.name,m.languages_enabled,0 AS count_check
                  FROM sml_maps AS m $where
                  ORDER BY m.date_created DESC, m.id DESC;";
            break;
        default:
            $query = "SELECT m.id,m.id_user,m.code,m.name,0 as count_check FROM sml_maps as m $where ORDER BY m.date_created DESC;";
            break;
    }
    $result = $mysqli->query($query);
    if($result) {
        if ($result->num_rows > 0) {
            while($row = $result->fetch_array(MYSQLI_ASSOC)) {
                switch($check) {
                    case 'bulk_translate':
                        $count_languages_enabled = 0;
                        if(!empty($row['languages_enabled'])) {
                            $row['languages_enabled']=json_decode($row['languages_enabled'],true);
                        } else {
                            $row['languages_enabled']=array();
                        }
                        foreach ($row['languages_enabled'] as $lang_enabled) {
                            if($lang_enabled==1) {
                                $count_languages_enabled++;
                            }
                        }
                        $row['count_check'] = $count_languages_enabled;
                        break;
                }
                $return[] = $row;
            }
        }
    }
    return $return;
}

function get_marker($id_marker,$id_user) {
    global $mysqli;
    $return = array();
    $query = "SELECT k.*,m.id_user,i.image as icon_image,GROUP_CONCAT(DISTINCT ca.id_category) as id_categories FROM sml_markers as k
                JOIN sml_maps as m ON m.id=k.id_map
                LEFT JOIN sml_icons as i ON i.id=k.id_icon_library
                LEFT JOIN sml_markers_categories_assoc as ca ON ca.id_marker=k.id
                WHERE k.id=? GROUP BY k.id LIMIT 1;";
    if($smt = $mysqli->prepare($query)) {
        $smt->bind_param('i',$id_marker);
        $result = $smt->execute();
        if($result) {
            $result = get_result($smt);
            if(count($result)==1) {
                $row = array_shift($result);
                $id_user_m = $row['id_user'];
                switch(get_user_role($id_user)) {
                    case 'customer':
                        if($id_user!=$id_user_m) return false;
                        break;
                }
                $row['icon'] = explode("|",$row['icon'])[0];
                if(empty($row['icon_image'])) $row['icon_image']='';
                for($i=1;$i<=20;$i++) {
                    $row['extra_field_value_'.$i] = htmlspecialchars_decode($row['extra_field_value_'.$i]);
                    $row['extra_field_value_'.$i] = str_replace(["\r\n","\r","\n"], "<br>", $row['extra_field_value_'.$i]);
                    $row['extra_field_value_'.$i] = str_replace('"', '\"', $row['extra_field_value_'.$i]);
                }
                $row['extra_button_value_1'] = htmlspecialchars_decode($row['extra_button_value_1']);
                $row['extra_button_value_1'] = str_replace(["\r\n","\r","\n"], "<br>", $row['extra_button_value_1']);
                $row['extra_button_value_1'] = str_replace('"', '\"', $row['extra_button_value_1']);
                $return=$row;
            }
        }
    }
    return $return;
}

function get_library_icons($id_map) {
    global $mysqli;
    $return = "";
    $query = "SELECT * FROM sml_icons WHERE id_map=? OR id_map IS NULL;";
    if($smt = $mysqli->prepare($query)) {
        $smt->bind_param('i',$id_map);
        $result = $smt->execute();
        if($result) {
            $result = get_result($smt);
            if(count($result)>0) {
                while($row = array_shift($result)) {
                    $id = $row['id'];
                    $image = $row['image'];
                    $return .= "<img onclick='select_icon_library($id,\"$image\");' style='display: inline-block;width:50px;padding: 3px;' src='../viewer/icons/$image' />";
                }
            } else {
                $return = _("No icons in this library.");
            }
        }
    }
    return $return;
}

function get_library_icons_c($id_map) {
    global $mysqli;
    $return = "";
    $query = "SELECT * FROM sml_icons WHERE id_map=? OR id_map IS NULL;";
    if($smt = $mysqli->prepare($query)) {
        $smt->bind_param('i',$id_map);
        $result = $smt->execute();
        if($result) {
            $result = get_result($smt);
            if(count($result)>0) {
                while($row = array_shift($result)) {
                    $id = $row['id'];
                    $image = $row['image'];
                    $return .= "<img onclick='select_icon_library_c($id,\"$image\");' style='display: inline-block;width:50px;padding: 3px;' src='../viewer/icons/$image' />";
                }
            } else {
                $return = _("No icons in this library.");
            }
        }
    }
    return $return;
}

function get_library_icons_pin($id_map) {
    global $mysqli;
    $return = "";
    $query = "SELECT * FROM sml_icons WHERE id_map=? OR id_map IS NULL;";
    if($smt = $mysqli->prepare($query)) {
        $smt->bind_param('i',$id_map);
        $result = $smt->execute();
        if($result) {
            $result = get_result($smt);
            if(count($result)>0) {
                while($row = array_shift($result)) {
                    $id = $row['id'];
                    $image = $row['image'];
                    $return .= "<img onclick='select_icon_library_pin($id,\"$image\");' style='display: inline-block;width:50px;padding: 3px;' src='../viewer/icons/$image' />";
                }
            } else {
                $return = _("No icons in this library.");
            }
        }
    }
    return $return;
}

function get_editor_permissions($id_user,$id_map) {
    global $mysqli;
    $query = "SELECT * FROM sml_assign_maps WHERE id_user=$id_user AND id_map=$id_map LIMIT 1;";
    $result = $mysqli->query($query);
    $return = array();
    if($result) {
        if($result->num_rows==1) {
            $row=$result->fetch_array(MYSQLI_ASSOC);
            $return=$row;
        }
    }
    return $return;
}

function get_reports($id_user) {
    global $mysqli;
    $array_maps = array();
    $array_num_markers = array();
    $where = "";
    $role = get_user_role($id_user);
    switch($role) {
        case 'administrator':
            $where = " WHERE 1=1 ";
            break;
        case 'customer':
            $where = " WHERE 1=1 AND m.id_user=? ";
            break;
        case 'editor':
            $where = " WHERE 1=1 AND m.id IN (0) ";
            $query = "SELECT GROUP_CONCAT(id_map) as ids FROM sml_assign_maps WHERE id_user=$id_user;";
            $result = $mysqli->query($query);
            if($result) {
                if($result->num_rows==1) {
                    $row=$result->fetch_array(MYSQLI_ASSOC);
                    $ids = $row['ids'];
                    if(!empty($ids)) {
                        $where = " WHERE 1=1 AND m.id IN ($ids) ";
                    }
                }
            }
            break;
    }
    $query = "SELECT COUNT(k.id) as num_markers,m.name as map FROM sml_markers as k
                JOIN sml_maps as m ON m.id=k.id_map
                $where AND k.to_validate=0
                GROUP BY m.id;";
    if($smt = $mysqli->prepare($query)) {
        if($role=='customer') {
            $smt->bind_param('i',$id_user);
        }
        $result = $smt->execute();
        if($result) {
            $result = get_result($smt);
            if(count($result)>0) {
                while($row = array_shift($result)) {
                    array_push($array_maps,$row['map']);
                    array_push($array_num_markers,$row['num_markers']);
                }
            }
        }
    }
    return json_encode(array("maps"=>$array_maps,"num_markers"=>$array_num_markers));
}

function get_categories_option($id_map) {
    global $mysqli;
    $options = "";
    $query = "SELECT c.id,c.name,scva.id_map 
                FROM sml_map_categories as c
                LEFT JOIN sml_category_map_assoc as scva on c.id = scva.id_category AND scva.id_map=$id_map
                ORDER BY c.position,name;";
    $result = $mysqli->query($query);
    if($result) {
        while($row=$result->fetch_array(MYSQLI_ASSOC)) {
            $id = $row['id'];
            $name = $row['name'];
            $assoc = $row['id_map'];
            if(!empty($assoc)) {
                $options .= "<option selected id='$id'>$name</option>";
            } else {
                $options .= "<option id='$id'>$name</option>";
            }
        }
    }
    return $options;
}

function get_categories_map() {
    global $mysqli;
    $return = array();
    $query = "SELECT * FROM sml_map_categories ORDER BY position;";
    $result = $mysqli->query($query);
    if($result) {
        if($result->num_rows>0) {
            while($row=$result->fetch_array(MYSQLI_ASSOC)) {
                $return[] = $row;
            }
        }
    }
    return $return;
}

function get_categories($id_map,$id_cat_sel) {
    global $mysqli;
    $return = array();
    $id_cat_sel = explode(",",$id_cat_sel);
    $query = "SELECT c.id,IF(ccc.name IS NOT NULL,CONCAT(ccc.name, ' - ', cc.name, ' - ', c.name),IF(cc.name IS NOT NULL,CONCAT(cc.name, ' - ', c.name),c.name)) as category,(SELECT COUNT(*) FROM sml_categories WHERE c.id=id_category_parent) as count_c
                FROM sml_categories as c
                LEFT JOIN sml_categories as cc ON c.id_category_parent=cc.id
                LEFT JOIN sml_categories as ccc ON cc.id_category_parent=ccc.id
                WHERE c.id_map=? 
                ORDER BY category;";
    if($smt = $mysqli->prepare($query)) {
        $smt->bind_param('i',$id_map);
        $result = $smt->execute();
        if($result) {
            $result = get_result($smt);
            if(count($result)>0) {
                while($row = array_shift($result)) {
                    $id = $row['id'];
                    $category = $row['category'];
                    if(in_array($id,$id_cat_sel)) {
                        $selected = "selected";
                    } else {
                        $selected = "";
                    }
                    if($row['count_c']>0) {
                        $disabled = "disabled";
                        $selected = "";
                    } else {
                        $disabled = "";
                    }
                    $return .= "<option $disabled $selected id='$id'>$category</option>";
                }
            }
        }
    }
    return $return;
}

function get_categories_viewer($id_map,$id_cat_sel,$language) {
    global $mysqli;
    $return = array();
    $id_cat_sel = explode(",",$id_cat_sel);
    $query = "SELECT c.id,c.default_am_fields,IF(ccc.name IS NOT NULL,CONCAT(COALESCE(cccl.name,ccc.name), ' - ', COALESCE(ccl.name,cc.name), ' - ', COALESCE(cl.name,c.name)),IF(cc.name IS NOT NULL,CONCAT(COALESCE(ccl.name,cc.name), ' - ', COALESCE(cl.name,c.name)),COALESCE(cl.name,c.name))) as category,(SELECT COUNT(*) FROM sml_categories WHERE c.id=id_category_parent) as count_c
                FROM sml_categories as c
                LEFT JOIN sml_categories as cc ON c.id_category_parent=cc.id AND cc.add_from_map=1
                LEFT JOIN sml_categories as ccc ON cc.id_category_parent=ccc.id AND ccc.add_from_map=1
                LEFT JOIN sml_categories_lang as cl ON c.id=cl.id_category AND cl.language='$language'
                LEFT JOIN sml_categories_lang as ccl ON cc.id=ccl.id_category AND ccl.language='$language'
                LEFT JOIN sml_categories_lang as cccl ON ccc.id=cccl.id_category AND cccl.language='$language'
                WHERE c.id_map=? AND c.add_from_map=1 
                ORDER BY category;";
    if($smt = $mysqli->prepare($query)) {
        $smt->bind_param('i',$id_map);
        $result = $smt->execute();
        if($result) {
            $result = get_result($smt);
            if(count($result)>0) {
                while($row = array_shift($result)) {
                    $id = $row['id'];
                    $category = $row['category'];
                    $default_am_fields = $row['default_am_fields'];
                    if(in_array($id,$id_cat_sel)) {
                        $selected = "selected";
                    } else {
                        $selected = "";
                    }
                    if($row['count_c']>0) {
                        $disabled = "disabled";
                    } else {
                        $disabled = "";
                    }
                    $return .= "<option data-am-fields='$default_am_fields' $disabled $selected id='$id'>$category</option>";
                }
            }
        }
    }
    return $return;
}

function get_parent_categories($id_map, $id_cat_sel, $id_category) {
    global $mysqli;
    $return = '';
    $query = "SELECT id, name FROM sml_categories WHERE id_map = ? AND id_category_parent IS NULL AND id!=$id_category ORDER BY name;";
    if ($smt = $mysqli->prepare($query)) {
        $smt->bind_param('i', $id_map);
        if ($smt->execute()) {
            $result = get_result($smt);
            foreach ($result as $row) {
                $id = $row['id'];
                $name = htmlspecialchars($row['name']);
                $selected = ($id == $id_cat_sel) ? "selected" : "";
                $return .= "<option id='$id' $selected>$name</option>";
                $query2 = "SELECT id, name FROM sml_categories WHERE id_map = ? AND id_category_parent = ? ORDER BY name;";
                if ($smt2 = $mysqli->prepare($query2)) {
                    $smt2->bind_param('ii', $id_map, $id);
                    if ($smt2->execute()) {
                        $subcategories = get_result($smt2);
                        foreach ($subcategories as $sub) {
                            $sub_id = $sub['id'];
                            $sub_name = htmlspecialchars($sub['name']);
                            $selected_sub = ($sub_id == $id_cat_sel) ? "selected" : "";
                            $return .= "<option id='$sub_id' $selected_sub>&nbsp;&nbsp;&nbsp;↳ $sub_name</option>";
                        }
                    }
                    $smt2->close();
                }
            }
        }
        $smt->close();
    }
    return $return;
}

function get_markers_options($id_map,$id_marker_sel) {
    global $mysqli;
    $return = array();
    $query = "SELECT m.id,m.name FROM sml_markers as m WHERE m.id_map=? AND m.to_validate=0 ORDER BY m.name;";
    if($smt = $mysqli->prepare($query)) {
        $smt->bind_param('i',$id_map);
        $result = $smt->execute();
        if($result) {
            $result = get_result($smt);
            if(count($result)>0) {
                while($row = array_shift($result)) {
                    $id = $row['id'];
                    $name = $row['name'];
                    if($id==$id_marker_sel) {
                        $selected = "selected";
                    } else {
                        $selected = "";
                    }
                    $return .= "<option $selected id='$id'>$name</option>";
                }
            }
        }
    }
    return $return;
}

function get_users($id_user_sel) {
    global $mysqli;
    $options = "";
    $count = 0;
    $query = "SELECT id,username,role FROM sml_users WHERE role IN('customer','administrator') ORDER BY username;";
    if($smt = $mysqli->prepare($query)) {
        $result = $smt->execute();
        if($result) {
            $result = get_result($smt);
            $count = count($result);
            if($count>0) {
                while($row = array_shift($result)) {
                    $id_user = $row['id'];
                    $username = $row['username'];
                    $role = $row['role'];
                    if ($role == 'administrator') $username = $username . " (" . _("administrator") . ")";
                    if ($id_user == $id_user_sel) {
                        $options .= "<option selected id='$id_user'>$username</option>";
                    } else {
                        $options .= "<option id='$id_user'>$username</option>";
                    }
                }
            }
        }
    }
    return array("options"=>$options,"count"=>$count);
}

function get_maps_options_css() {
    global $mysqli;
    $return = "";
    $query = "SELECT code,name FROM sml_maps ORDER BY name ASC;";
    $result = $mysqli->query($query);
    if($result) {
        if($result->num_rows>0) {
            while($row=$result->fetch_array(MYSQLI_ASSOC)) {
                $code = $row['code'];
                $name = $row['name'];
                $return .= "<option id='css_custom_$code'>$name</option>";
            }
        }
    }
    return $return;
}

function get_maps_options_js() {
    global $mysqli;
    $return = "";
    $query = "SELECT code,name FROM sml_maps ORDER BY name ASC;";
    $result = $mysqli->query($query);
    if($result) {
        if($result->num_rows>0) {
            while($row=$result->fetch_array(MYSQLI_ASSOC)) {
                $code = $row['code'];
                $name = $row['name'];
                $return .= "<option id='js_custom_$code'>$name</option>";
            }
        }
    }
    return $return;
}

function get_maps_options_head() {
    global $mysqli;
    $return = "";
    $query = "SELECT code,name FROM sml_maps ORDER BY name ASC;";
    $result = $mysqli->query($query);
    if($result) {
        if($result->num_rows>0) {
            while($row=$result->fetch_array(MYSQLI_ASSOC)) {
                $code = $row['code'];
                $name = $row['name'];
                $return .= "<option id='head_custom_$code'>$name</option>";
            }
        }
    }
    return $return;
}

function get_editor_css_content($css) {
    if($css=='custom_b') {
        $url_css = __DIR__.DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'backend'.DIRECTORY_SEPARATOR.'css'.DIRECTORY_SEPARATOR.'custom_b.css';
        if(file_exists($url_css)) {
            return @file_get_contents($url_css);
        } else {
            return '';
        }
    } else {
        $url_css = __DIR__.DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'viewer'.DIRECTORY_SEPARATOR.'css'.DIRECTORY_SEPARATOR.$css.'.css';
        if(file_exists($url_css)) {
            return @file_get_contents($url_css);
        } else {
            return '';
        }
    }
}

function get_editor_js_content($js) {
    if($js=='custom_b') {
        $url_js = __DIR__.DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'backend'.DIRECTORY_SEPARATOR.'js'.DIRECTORY_SEPARATOR.'custom_b.js';
    } else {
        $url_js = __DIR__.DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'viewer'.DIRECTORY_SEPARATOR.'js'.DIRECTORY_SEPARATOR.$js.'.js';
    }
    if(file_exists($url_js)) {
        return @file_get_contents($url_js);
    } else {
        return '';
    }
}

function get_editor_head_content($header) {
    if($header=='custom_b') {
        $url_header = __DIR__.DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'backend'.DIRECTORY_SEPARATOR.'header'.DIRECTORY_SEPARATOR.'custom_b.php';
    } else {
        $url_header = __DIR__.DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'viewer'.DIRECTORY_SEPARATOR.'header'.DIRECTORY_SEPARATOR.$header.'.php';
    }
    if(file_exists($url_header)) {
        return @file_get_contents($url_header);
    } else {
        return '';
    }
}

function get_maps_editors_css() {
    global $mysqli;
    $return = "";
    $query = "SELECT code FROM sml_maps;";
    $result = $mysqli->query($query);
    if($result) {
        if($result->num_rows>0) {
            while($row=$result->fetch_array(MYSQLI_ASSOC)) {
                $code = $row['code'];
                $return .= '<div style="display:none;position: relative;width: 100%;height: 400px;" class="editors_css" id="custom_'.$code.'">'.get_editor_css_content('custom_'.$code).'</div>';
            }
        }
    }
    return $return;
}

function get_maps_editors_js() {
    global $mysqli;
    $return = "";
    $query = "SELECT code FROM sml_maps;";
    $result = $mysqli->query($query);
    if($result) {
        if($result->num_rows>0) {
            while($row=$result->fetch_array(MYSQLI_ASSOC)) {
                $code = $row['code'];
                $return .= '<div style="display:none;position: relative;width: 100%;height: 400px;" class="editors_js" id="custom_js_'.$code.'">'.htmlspecialchars(get_editor_js_content('custom_'.$code)).'</div>';
            }
        }
    }
    return $return;
}

function get_maps_editors_head() {
    global $mysqli;
    $return = "";
    $query = "SELECT code FROM sml_maps;";
    $result = $mysqli->query($query);
    if($result) {
        if($result->num_rows>0) {
            while($row=$result->fetch_array(MYSQLI_ASSOC)) {
                $code = $row['code'];
                $return .= '<div style="display:none;position: relative;width: 100%;height: 400px;" class="editors_head" id="custom_head_'.$code.'">'.htmlspecialchars(get_editor_head_content('custom_'.$code)).'</div>';
            }
        }
    }
    return $return;
}

function get_next_prev_marker_id($id_marker,$id_map) {
    global $mysqli;
    $array_markers = array();
    $query = "SELECT id FROM sml_markers WHERE id_map=$id_map ORDER BY id;";
    $result = $mysqli->query($query);
    if($result) {
        while($row=$result->fetch_array(MYSQLI_ASSOC)) {
            $id = $row['id'];
            array_push($array_markers,$id);
        }
    }
    $index = array_search($id_marker,$array_markers);
    $len = count($array_markers);
    $prev_id = $array_markers[($index+$len-1)%$len];
    $next_id = $array_markers[($index+1)%$len];
    return [$next_id,$prev_id];
}

function get_next_prev_category_id($id_category,$id_map) {
    global $mysqli;
    $array_categories = array();
    $query = "SELECT id FROM sml_categories WHERE id_map=$id_map ORDER BY id;";
    $result = $mysqli->query($query);
    if($result) {
        while($row=$result->fetch_array(MYSQLI_ASSOC)) {
            $id = $row['id'];
            array_push($array_categories,$id);
        }
    }
    $index = array_search($id_category,$array_categories);
    $len = count($array_categories);
    $prev_id = $array_categories[($index+$len-1)%$len];
    $next_id = $array_categories[($index+1)%$len];
    return [$next_id,$prev_id];
}

function get_missing_coordinates_markers($id_map) {
    global $mysqli;
    $return = array();
    $query = "SELECT id,street,city,postal_code,country,county,state FROM sml_markers WHERE id_map=$id_map AND (lat='' OR lat IS NULL OR lon='' OR lon IS NULL) AND street!='';";
    $result = $mysqli->query($query);
    if($result) {
        if($result->num_rows>0) {
            while($row=$result->fetch_array(MYSQLI_ASSOC)) {
                $row['street']=str_replace(array("\r","\n","\t"),' ',$row['street']);
                $row['city']=str_replace(array("\r","\n","\t"),' ',$row['city']);
                $row['postal_code']=str_replace(array("\r","\n","\t"),' ',$row['postal_code']);
                $row['country']=str_replace(array("\r","\n","\t"),' ',$row['country']);
                $row['county']=str_replace(array("\r","\n","\t"),' ',$row['county']);
                $row['state']=str_replace(array("\r","\n","\t"),' ',$row['state']);
                $return[]=$row;
            }
        }
    }
    return $return;
}

function get_missing_address_markers($id_map) {
    global $mysqli;
    $return = array();
    $query = "SELECT id,lat,lon FROM sml_markers WHERE id_map=$id_map AND (lat!='' AND lat IS NOT NULL AND lon!='' AND lon IS NOT NULL) AND (street='' OR street IS NULL) AND (city='' OR city IS NULL) AND (postal_code='' OR postal_code IS NULL) AND (county='' OR county IS NULL) AND (country='' OR country IS NULL) AND (state='' OR state IS NULL);";
    $result = $mysqli->query($query);
    if($result) {
        if($result->num_rows>0) {
            while($row=$result->fetch_array(MYSQLI_ASSOC)) {
                $return[]=$row;
            }
        }
    }
    return $return;
}

function count_markers($id_map) {
    global $mysqli;
    $num = 0;
    $query = "SELECT COUNT(id) as num FROM sml_markers WHERE id_map=$id_map;";
    $result = $mysqli->query($query);
    if($result) {
        $row=$result->fetch_array(MYSQLI_ASSOC);
        $num=$row['num'];
    }
    return $num;
}

function print_map_selector($check='no') {
    $id_user = $_SESSION['id_user'];
    $maps = get_maps($id_user,($check=='preview') ? 'no' : $check);
    $count_maps = count($maps);
    $array_list_map = array();
    if ($count_maps==1) {
        $id_map_sel = $maps[0]['id'];
        $name_map_sel = $maps[0]['name'];
        $author_map_sel = $maps[0]['author'];
        $_SESSION['id_map_sel'] = $id_map_sel;
        $_SESSION['name_map_sel'] = $name_map_sel;
        $array_list_map[] = array("id"=>$id_map_sel,"name"=>$name_map_sel,"author"=>$author_map_sel,"code"=>$maps[0]['code']);
    } else {
        if(isset($_GET['id_map'])) {
            $id_map_sel = $_GET['id_map'];
            $name_map_sel = get_map($_GET['id_map'],$id_user)['name'];
            $_SESSION['id_map_sel'] = $id_map_sel;
            $_SESSION['name_map_sel'] = $name_map_sel;
        } else {
            if(isset($_SESSION['id_map_sel'])) {
                $id_map_sel = $_SESSION['id_map_sel'];
            } else {
                $id_map_sel = $maps[0]['id'];
                $name_map_sel = $maps[0]['name'];
                $_SESSION['id_map_sel'] = $id_map_sel;
                $_SESSION['name_map_sel'] = $name_map_sel;
            }
        }
        foreach ($maps as $map) {
            $id_map = $map['id'];
            $name_map = $map['name'];
            $count_check = $map['count_check'];
            $array_list_map[] = array("id"=>$id_map,"name"=>$name_map,"count_check"=>$count_check,"code"=>$map['code']);
        }
    }
    $return = '<div class="map_select_header">';
    $return .= '<i id="loading_header" class="fas fa-spin fa-spinner"></i>';
    $return .= '<select onchange="change_map();" id="map_selector" class="selectpicker" data-virtual-scroll="true" data-container="#map_select" data-width="fit" data-live-search="true" data-style="map_selector_btn" data-none-results-text="'._("No results matched").' {0}">';
    foreach ($array_list_map as $map) {
        $map['name'] = htmlentities($map['name']);
        $name_map = $map['name'];
        if($check=='no' || $check=='preview') {
            $icon = "";
        } else {
            if($map['count_check']>0) {
                $icon = "data-icon='fas fa-circle'";
            } else {
                $icon = "data-icon='far fa-circle'";
            }
        }
        $return .= "<option data-code='".$map['code']."' $icon ".(($id_map_sel==$map['id']) ? 'selected' : '')." id='".$map['id']."'>".$name_map."</option>";
    }
    $return .= '</select>';
    $return .= '<a title="'._("EDIT MAP").'" href="index.php?p=edit_map&id='.$id_map_sel.'" class="quick_action"><i class="fas fa-edit"></i></a>';
    $return .= '&nbsp;&nbsp;&nbsp;';
    $return .= '<a title="'._("PREVIEW").'" onclick="open_preview_global_viewer();return false;" href="#" id="btn_preview" class="quick_action"><i class="fas fa-eye"></i></a>';
    $return .= '</div>';
    return $return;
}

function get_showcase($id_showcase,$id_user) {
    global $mysqli;
    $return = array();
    $query = "SELECT * FROM sml_showcases WHERE id = $id_showcase LIMIT 1;";
    $result = $mysqli->query($query);
    if($result) {
        if($result->num_rows==1) {
            $row=$result->fetch_array(MYSQLI_ASSOC);
            $id_user_s = $row['id_user'];
            $row['header_html'] = htmlspecialchars_decode($row['header_html']);
            $row['footer_html'] = htmlspecialchars_decode($row['footer_html']);
            $row['header_html'] = str_replace(["\r\n","\r","\n"], "<br>", $row['header_html']);
            $row['footer_html'] = str_replace(["\r\n","\r","\n"], "<br>", $row['footer_html']);
            $row['header_html'] = str_replace('"', '\"', $row['header_html']);
            $row['footer_html'] = str_replace('"', '\"', $row['footer_html']);
            if(empty($row['languages_enabled'])) {
                $row['languages_enabled']=array();
            } else {
                $row['languages_enabled']=json_decode($row['languages_enabled'],true);
            }
            switch(get_user_role($id_user)) {
                case 'administrator';
                    break;
                case 'customer':
                    if($id_user!=$id_user_s) return false;
                    break;
                case 'editor':
                    return false;
                    break;
            }
            $return=$row;
        }
    }
    return $return;
}

function get_showcase_maps($id_user,$id_showcase) {
    global $mysqli;
    $return = "";
    $where = "";
    switch(get_user_role($id_user)) {
        case 'administrator';
            $where = "";
            break;
        case 'customer':
            $where = "WHERE v.id_user=$id_user";
            break;
        case 'editor':
            return '';
            break;
    }
    $query = "SELECT v.id,v.name,s.id_map as id_s,s.priority FROM sml_maps AS v
                LEFT JOIN sml_showcase_list AS s ON s.id_map=v.id AND s.id_showcase=$id_showcase
                $where
                ORDER BY IFNULL(s.priority,9999),v.date_created;";
    $result = $mysqli->query($query);
    if($result) {
        if($result->num_rows>0) {
            while($row=$result->fetch_array(MYSQLI_ASSOC)) {
                $id = $row['id'];
                $name = $row['name'];
                $id_s = $row['id_s'];
                $priority = $row['priority'];
                $priority_input = "<i style='display:none;cursor:pointer;' class='fas move_map fa-arrows-alt'></i> <input style='display:none;width:30px;font-size:12px;vertical-align:text-bottom' id='p_$id' class='map_priority' data-id-map='$id' readonly type='text' value='$priority' />";
                if (!empty($id_s)) {
                    $return .= "<div class='col-md-4 mb-1 map_block'><label><input onchange='fix_map_priority();' id='$id' checked type='checkbox'>$priority_input $name</label></div>";
                } else {
                    $return .= "<div class='col-md-4 mb-1 map_block'><label><input onchange='fix_map_priority();' id='$id' type='checkbox'>$priority_input $name</label></div>";
                }
            }
        }
    }
    return $return;
}

function get_maps_options($id_map_sel) {
    global $mysqli;
    $return = "";
    $query = "SELECT id,name FROM sml_maps ORDER BY name ASC;";
    $result = $mysqli->query($query);
    if($result) {
        if($result->num_rows>0) {
            while($row=$result->fetch_array(MYSQLI_ASSOC)) {
                $id = $row['id'];
                $name = $row['name'];
                if($id==$id_map_sel) {
                    $return .= "<option selected id='$id'>$name</option>";
                } else {
                    $return .= "<option id='$id'>$name</option>";
                }
            }
        }
    }
    return $return;
}

function get_editor_css_content_s($css) {
    $url_css = __DIR__.DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'showcase'.DIRECTORY_SEPARATOR.'css'.DIRECTORY_SEPARATOR.$css.'.css';
    if(file_exists($url_css)) {
        return @file_get_contents($url_css);
    } else {
        return '';
    }
}

function formatTime($format, $language = null, $timestamp = null) {
    if (!is_numeric($timestamp)) {
        return "";
    }
    if (class_exists('IntlDateFormatter')) {
        $locale = ($language !== null) ? $language : 'en_US';
        $timezone = date_default_timezone_get();
        $dateStyle = defined('IntlDateFormatter::FULL') ? IntlDateFormatter::FULL : 0;
        $timeStyle = defined('IntlDateFormatter::FULL') ? IntlDateFormatter::FULL : 0;
        $formatter = new IntlDateFormatter(
            $locale,
            $dateStyle,
            $timeStyle,
            $timezone
        );
        if ($formatter) {
            $formatter->setPattern($format);
            $formattedDateTime = $formatter->format($timestamp);
        }
    } else {
        switch($format) {
            case 'dd MMM y':
                $format = "d M Y";
                break;
            case 'dd MMM y - HH:mm':
                $format = "d M Y - H:i";
                break;
            default:
                $format = "d M Y";
                break;
        }
        $formattedDateTime = date($format,$timestamp);
    }
    return $formattedDateTime;
}

function get_ip_server() {
    $server_ip = '';
    $server_name = $_SERVER['SERVER_NAME'];
    if(array_key_exists('SERVER_ADDR', $_SERVER)) {
        $server_ip = $_SERVER['SERVER_ADDR'];
        if(!filter_var($server_ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
            $server_ip = gethostbyname($server_name);
        }
    } elseif(array_key_exists('LOCAL_ADDR', $_SERVER)) {
        $server_ip = $_SERVER['LOCAL_ADDR'];
    } elseif(array_key_exists('SERVER_NAME', $_SERVER)) {
        $server_ip = gethostbyname($_SERVER['SERVER_NAME']);
    } else {
        if(stristr(PHP_OS, 'WIN')) {
            $server_ip = gethostbyname(php_uname("n"));
        } else {
            $ifconfig = shell_exec('/sbin/ifconfig eth0');
            preg_match('/addr:([\d\.]+)/', $ifconfig, $match);
            $server_ip = $match[1];
        }
    }
    return $server_ip;
}

function get_string_between($string, $start, $end){
    $string = ' ' . $string;
    $ini = strpos($string, $start);
    if ($ini == 0) return '';
    $ini += strlen($start);
    $len = strpos($string, $end, $ini) - $ini;
    return substr($string, $ini, $len);
}

function get_result(\mysqli_stmt $statement) {
    $result = array();
    $statement->store_result();
    for ($i = 0; $i < $statement->num_rows; $i++)
    {
        $metadata = $statement->result_metadata();
        $params = array();
        while ($field = $metadata->fetch_field())
        {
            $params[] = &$result[$i][$field->name];
        }
        call_user_func_array(array($statement, 'bind_result'), $params);
        $statement->fetch();
    }
    return $result;
}

function curl_get_file_contents($url) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_USERAGENT, base64_decode('c21sX3VzZXJfYWdlbnQ='));
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_REFERER, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
    $result = curl_exec($ch);
    curl_close($ch);
    return $result;
}

function getCenterLatLng($coordinates) {
    $x = $y = $z = 0;
    $n = count($coordinates);
    foreach ($coordinates as $point) {
        $lt = $point[0] * pi() / 180;
        $lg = $point[1] * pi() / 180;
        $x += cos($lt) * cos($lg);
        $y += cos($lt) * sin($lg);
        $z += sin($lt);
    }
    $x /= $n;
    $y /= $n;
    return [atan2(($z / $n), sqrt($x * $x + $y * $y)) * 180 / pi(), atan2($y, $x) * 180 / pi()];
}

function encrypt_decrypt($action, $string, $secret_key = "supersecret_key") {
    $output = false;
    $encrypt_method = "AES-256-CBC";
    $secret_iv = '#sml#';
    $key = hash('sha256', $secret_key);
    $iv = substr(hash('sha256', $secret_iv), 0, 16);
    if ( $action == 'encrypt' ) {
        $output = openssl_encrypt($string, $encrypt_method, $key, 0, $iv);
        $output = base64_encode($output);
    } else if( $action == 'decrypt' ) {
        $output = openssl_decrypt(base64_decode($string), $encrypt_method, $key, 0, $iv);
    }
    return $output;
}

function generate_favicons($what,$id) {
    require_once(__DIR__ . "/../config/config.inc.php");
    if (defined('PHP_PATH')) {
        $path_php = PHP_PATH;
    } else {
        $path_php = '';
    }
    $currentPath = $_SERVER['PHP_SELF'];
    $pathInfo = pathinfo($currentPath);
    $hostName = $_SERVER['HTTP_HOST'];
    if (is_ssl()) { $protocol = 'https'; } else { $protocol = 'http'; }
    $url = $protocol."://".$hostName.$pathInfo['dirname'];
    if(isEnabled('shell_exec')) {
        try {
            if(empty($path_php)) {
                $command = 'command -v php 2>&1';
                $output = shell_exec($command);
                if(empty($output)) $output = PHP_BINARY;
                $path_php = trim($output);
                $path_php = str_replace("sbin/php-fpm","bin/php",$path_php);
            }
            $path = realpath(dirname(__FILE__) . '/..');
            $command = $path_php." ".$path.DIRECTORY_SEPARATOR."services".DIRECTORY_SEPARATOR."generate_favicons.php $url $what $id > /dev/null &";
            shell_exec($command);
        } catch (Exception $e) {
            return '../services/generate_favicons.php?id='.$id.'&what='.$what.'&url='.$url;
        }
        return 1;
    } else {
        return '../services/generate_favicons.php?id='.$id.'&what='.$what.'&url='.$url;
    }
}

function print_favicons_backend($logo, $theme_color) {
    $path = '';
    $version = time();
    if (file_exists(dirname(__FILE__).'/../favicons/custom/favicon.ico')) {
        $path = 'custom/';
        $version = preg_replace('/[^0-9]/', '', $logo);
    }
    $apple_touch = "";
    if (file_exists(dirname(__FILE__).'/../favicons/'.$path.'apple-touch-icon.png')) {
        $apple_touch = '<link rel="apple-touch-icon" sizes="180x180" href="../favicons/'.$path.'apple-touch-icon.png?v='.$version.'">';
    }
    $favicon32 = "";
    if (file_exists(dirname(__FILE__).'/../favicons/'.$path.'favicon-32x32.png')) {
        $favicon32 = '<link rel="icon" type="image/png" sizes="32x32" href="../favicons/'.$path.'favicon-32x32.png?v='.$version.'">';
    }
    $favicon16 = "";
    if (file_exists(dirname(__FILE__).'/../favicons/'.$path.'favicon-16x16.png')) {
        $favicon16 = '<link rel="icon" type="image/png" sizes="16x16" href="../favicons/'.$path.'favicon-16x16.png?v='.$version.'">';
    }
    $manifest = "";
    if (file_exists(dirname(__FILE__).'/../favicons/'.$path.'site.webmanifest')) {
        $manifest = '<link rel="manifest" href="../favicons/'.$path.'site.webmanifest?v='.$version.'">';
    }
    $safari_pinned = "";
    if (file_exists(dirname(__FILE__).'/../favicons/'.$path.'safari-pinned-tab.svg')) {
        $safari_pinned = '<link rel="mask-icon" href="../favicons/'.$path.'safari-pinned-tab.svg?v='.$version.'" color="'.$theme_color.'">';
    }
    $favicon_ico = "";
    if (file_exists(dirname(__FILE__).'/../favicons/'.$path.'favicon.ico')) {
        $favicon_ico = '<link rel="shortcut icon" href="../favicons/'.$path.'favicon.ico?v='.$version.'">';
    }
    $browserconfig = "";
    if (file_exists(dirname(__FILE__).'/../favicons/'.$path.'browserconfig.xml')) {
        $browserconfig = '<meta name="msapplication-config" content="../favicons/'.$path.'browserconfig.xml?v='.$version.'">';
    }
    return $apple_touch.'
    '.$favicon32.'
    '.$favicon16.'
    '.$manifest.'
    '.$safari_pinned.'
    '.$favicon_ico.'
    <meta name="msapplication-TileColor" content="'.$theme_color.'">
    '.$browserconfig.'
    <meta name="theme-color" content="'.$theme_color.'">';
}

function fix_zoom_levels(&$minzoom, &$maxzoom) {
    $minzoom = max(1, min(20, $minzoom));
    $maxzoom = max(1, min(20, $maxzoom));
    if ($minzoom > $maxzoom) {
        $minzoom = $maxzoom;
    }
}

function isEnabled($func) {
    return is_callable($func) && false === stripos(ini_get('disable_functions'), $func);
}

if (!function_exists('generateAdvancedPhoneInput')) {
    $prefixes = [
        ['code' => '+93', 'country' => 'Afghanistan'], ['code' => '+355', 'country' => 'Albania'],
        ['code' => '+213', 'country' => 'Algeria'], ['code' => '+1684', 'country' => 'American Samoa'],
        ['code' => '+376', 'country' => 'Andorra'], ['code' => '+244', 'country' => 'Angola'],
        ['code' => '+1264', 'country' => 'Anguilla'], ['code' => '+672', 'country' => 'Antarctica'],
        ['code' => '+1268', 'country' => 'Antigua & Barbuda'], ['code' => '+54', 'country' => 'Argentina'],
        ['code' => '+374', 'country' => 'Armenia'], ['code' => '+297', 'country' => 'Aruba'],
        ['code' => '+61', 'country' => 'Australia'], ['code' => '+43', 'country' => 'Austria'],
        ['code' => '+994', 'country' => 'Azerbaijan'], ['code' => '+1242', 'country' => 'Bahamas'],
        ['code' => '+973', 'country' => 'Bahrain'], ['code' => '+880', 'country' => 'Bangladesh'],
        ['code' => '+1246', 'country' => 'Barbados'], ['code' => '+375', 'country' => 'Belarus'],
        ['code' => '+32', 'country' => 'Belgium'], ['code' => '+501', 'country' => 'Belize'],
        ['code' => '+229', 'country' => 'Benin'], ['code' => '+1441', 'country' => 'Bermuda'],
        ['code' => '+975', 'country' => 'Bhutan'], ['code' => '+591', 'country' => 'Bolivia'],
        ['code' => '+387', 'country' => 'Bosnia & Herzegovina'], ['code' => '+267', 'country' => 'Botswana'],
        ['code' => '+55', 'country' => 'Brazil'], ['code' => '+246', 'country' => 'British Indian Ocean Territory'],
        ['code' => '+1284', 'country' => 'British Virgin Islands'], ['code' => '+673', 'country' => 'Brunei'],
        ['code' => '+359', 'country' => 'Bulgaria'], ['code' => '+226', 'country' => 'Burkina Faso'],
        ['code' => '+257', 'country' => 'Burundi'], ['code' => '+855', 'country' => 'Cambodia'],
        ['code' => '+237', 'country' => 'Cameroon'], ['code' => '+1', 'country' => 'Canada'],
        ['code' => '+238', 'country' => 'Cape Verde'], ['code' => '+1345', 'country' => 'Cayman Islands'],
        ['code' => '+236', 'country' => 'Central African Republic'], ['code' => '+235', 'country' => 'Chad'],
        ['code' => '+56', 'country' => 'Chile'], ['code' => '+86', 'country' => 'China'],
        ['code' => '+61', 'country' => 'Christmas Island'], ['code' => '+61', 'country' => 'Cocos (Keeling) Islands'],
        ['code' => '+57', 'country' => 'Colombia'], ['code' => '+269', 'country' => 'Comoros'],
        ['code' => '+243', 'country' => 'Congo (DRC)'], ['code' => '+242', 'country' => 'Congo (Republic)'],
        ['code' => '+682', 'country' => 'Cook Islands'], ['code' => '+506', 'country' => 'Costa Rica'],
        ['code' => '+385', 'country' => 'Croatia'], ['code' => '+53', 'country' => 'Cuba'],
        ['code' => '+599', 'country' => 'Curaçao'], ['code' => '+357', 'country' => 'Cyprus'],
        ['code' => '+420', 'country' => 'Czech Republic'], ['code' => '+225', 'country' => 'Côte d\'Ivoire'],
        ['code' => '+45', 'country' => 'Denmark'], ['code' => '+253', 'country' => 'Djibouti'],
        ['code' => '+1767', 'country' => 'Dominica'], ['code' => '+1', 'country' => 'Dominican Republic'],
        ['code' => '+593', 'country' => 'Ecuador'], ['code' => '+20', 'country' => 'Egypt'],
        ['code' => '+503', 'country' => 'El Salvador'], ['code' => '+240', 'country' => 'Equatorial Guinea'],
        ['code' => '+291', 'country' => 'Eritrea'], ['code' => '+372', 'country' => 'Estonia'],
        ['code' => '+268', 'country' => 'Eswatini (Swaziland)'], ['code' => '+251', 'country' => 'Ethiopia'],
        ['code' => '+500', 'country' => 'Falkland Islands'], ['code' => '+298', 'country' => 'Faroe Islands'],
        ['code' => '+679', 'country' => 'Fiji'], ['code' => '+358', 'country' => 'Finland'],
        ['code' => '+33', 'country' => 'France'], ['code' => '+594', 'country' => 'French Guiana'],
        ['code' => '+689', 'country' => 'French Polynesia'], ['code' => '+241', 'country' => 'Gabon'],
        ['code' => '+220', 'country' => 'Gambia'], ['code' => '+995', 'country' => 'Georgia'],
        ['code' => '+49', 'country' => 'Germany'], ['code' => '+233', 'country' => 'Ghana'],
        ['code' => '+350', 'country' => 'Gibraltar'], ['code' => '+30', 'country' => 'Greece'],
        ['code' => '+299', 'country' => 'Greenland'], ['code' => '+1473', 'country' => 'Grenada'],
        ['code' => '+590', 'country' => 'Guadeloupe'], ['code' => '+1671', 'country' => 'Guam'],
        ['code' => '+502', 'country' => 'Guatemala'], ['code' => '+44-1481', 'country' => 'Guernsey'],
        ['code' => '+224', 'country' => 'Guinea'], ['code' => '+245', 'country' => 'Guinea-Bissau'],
        ['code' => '+592', 'country' => 'Guyana'], ['code' => '+509', 'country' => 'Haiti'],
        ['code' => '+504', 'country' => 'Honduras'], ['code' => '+852', 'country' => 'Hong Kong'],
        ['code' => '+36', 'country' => 'Hungary'], ['code' => '+354', 'country' => 'Iceland'],
        ['code' => '+91', 'country' => 'India'], ['code' => '+62', 'country' => 'Indonesia'],
        ['code' => '+98', 'country' => 'Iran'], ['code' => '+964', 'country' => 'Iraq'],
        ['code' => '+353', 'country' => 'Ireland'], ['code' => '+44-1624', 'country' => 'Isle of Man'],
        ['code' => '+972', 'country' => 'Israel'], ['code' => '+39', 'country' => 'Italy'],
        ['code' => '+1876', 'country' => 'Jamaica'], ['code' => '+81', 'country' => 'Japan'],
        ['code' => '+44-1534', 'country' => 'Jersey'], ['code' => '+962', 'country' => 'Jordan'],
        ['code' => '+7', 'country' => 'Kazakhstan'], ['code' => '+254', 'country' => 'Kenya'],
        ['code' => '+686', 'country' => 'Kiribati'], ['code' => '+383', 'country' => 'Kosovo'],
        ['code' => '+965', 'country' => 'Kuwait'], ['code' => '+996', 'country' => 'Kyrgyzstan'],
        ['code' => '+856', 'country' => 'Laos'], ['code' => '+371', 'country' => 'Latvia'],
        ['code' => '+961', 'country' => 'Lebanon'], ['code' => '+266', 'country' => 'Lesotho'],
        ['code' => '+231', 'country' => 'Liberia'], ['code' => '+218', 'country' => 'Libya'],
        ['code' => '+423', 'country' => 'Liechtenstein'], ['code' => '+370', 'country' => 'Lithuania'],
        ['code' => '+352', 'country' => 'Luxembourg'], ['code' => '+853', 'country' => 'Macau'],
        ['code' => '+261', 'country' => 'Madagascar'], ['code' => '+265', 'country' => 'Malawi'],
        ['code' => '+60', 'country' => 'Malaysia'], ['code' => '+960', 'country' => 'Maldives'],
        ['code' => '+223', 'country' => 'Mali'], ['code' => '+356', 'country' => 'Malta'],
        ['code' => '+692', 'country' => 'Marshall Islands'], ['code' => '+596', 'country' => 'Martinique'],
        ['code' => '+222', 'country' => 'Mauritania'], ['code' => '+230', 'country' => 'Mauritius'],
        ['code' => '+262', 'country' => 'Mayotte'], ['code' => '+52', 'country' => 'Mexico'],
        ['code' => '+691', 'country' => 'Micronesia'], ['code' => '+373', 'country' => 'Moldova'],
        ['code' => '+377', 'country' => 'Monaco'], ['code' => '+976', 'country' => 'Mongolia'],
        ['code' => '+382', 'country' => 'Montenegro'], ['code' => '+1664', 'country' => 'Montserrat'],
        ['code' => '+212', 'country' => 'Morocco'], ['code' => '+258', 'country' => 'Mozambique'],
        ['code' => '+95', 'country' => 'Myanmar (Burma)'], ['code' => '+264', 'country' => 'Namibia'],
        ['code' => '+674', 'country' => 'Nauru'], ['code' => '+977', 'country' => 'Nepal'],
        ['code' => '+31', 'country' => 'Netherlands'], ['code' => '+599', 'country' => 'Netherlands Antilles'],
        ['code' => '+687', 'country' => 'New Caledonia'], ['code' => '+64', 'country' => 'New Zealand'],
        ['code' => '+505', 'country' => 'Nicaragua'], ['code' => '+227', 'country' => 'Niger'],
        ['code' => '+234', 'country' => 'Nigeria'], ['code' => '+683', 'country' => 'Niue'],
        ['code' => '+672', 'country' => 'Norfolk Island'], ['code' => '+850', 'country' => 'North Korea'],
        ['code' => '+389', 'country' => 'North Macedonia'], ['code' => '+1670', 'country' => 'Northern Mariana Islands'],
        ['code' => '+47', 'country' => 'Norway'], ['code' => '+968', 'country' => 'Oman'],
        ['code' => '+92', 'country' => 'Pakistan'], ['code' => '+680', 'country' => 'Palau'],
        ['code' => '+970', 'country' => 'Palestine'], ['code' => '+507', 'country' => 'Panama'],
        ['code' => '+675', 'country' => 'Papua New Guinea'], ['code' => '+595', 'country' => 'Paraguay'],
        ['code' => '+51', 'country' => 'Peru'], ['code' => '+63', 'country' => 'Philippines'],
        ['code' => '+870', 'country' => 'Pitcairn Islands'], ['code' => '+48', 'country' => 'Poland'],
        ['code' => '+351', 'country' => 'Portugal'], ['code' => '+1', 'country' => 'Puerto Rico'],
        ['code' => '+974', 'country' => 'Qatar'], ['code' => '+40', 'country' => 'Romania'],
        ['code' => '+7', 'country' => 'Russia'], ['code' => '+250', 'country' => 'Rwanda'],
        ['code' => '+262', 'country' => 'Réunion'], ['code' => '+590', 'country' => 'Saint Barthélemy'],
        ['code' => '+290', 'country' => 'Saint Helena'], ['code' => '+1869', 'country' => 'Saint Kitts & Nevis'],
        ['code' => '+1758', 'country' => 'Saint Lucia'], ['code' => '+590', 'country' => 'Saint Martin'],
        ['code' => '+508', 'country' => 'Saint Pierre & Miquelon'], ['code' => '+1784', 'country' => 'Saint Vincent & Grenadines'],
        ['code' => '+685', 'country' => 'Samoa'], ['code' => '+378', 'country' => 'San Marino'],
        ['code' => '+239', 'country' => 'São Tomé & Príncipe'], ['code' => '+966', 'country' => 'Saudi Arabia'],
        ['code' => '+221', 'country' => 'Senegal'], ['code' => '+381', 'country' => 'Serbia'],
        ['code' => '+248', 'country' => 'Seychelles'], ['code' => '+232', 'country' => 'Sierra Leone'],
        ['code' => '+65', 'country' => 'Singapore'], ['code' => '+1721', 'country' => 'Sint Maarten'],
        ['code' => '+421', 'country' => 'Slovakia'], ['code' => '+386', 'country' => 'Slovenia'],
        ['code' => '+677', 'country' => 'Solomon Islands'], ['code' => '+252', 'country' => 'Somalia'],
        ['code' => '+27', 'country' => 'South Africa'], ['code' => '+82', 'country' => 'South Korea'],
        ['code' => '+211', 'country' => 'South Sudan'], ['code' => '+34', 'country' => 'Spain'],
        ['code' => '+94', 'country' => 'Sri Lanka'], ['code' => '+249', 'country' => 'Sudan'],
        ['code' => '+597', 'country' => 'Suriname'], ['code' => '+47', 'country' => 'Svalbard & Jan Mayen'],
        ['code' => '+46', 'country' => 'Sweden'], ['code' => '+41', 'country' => 'Switzerland'],
        ['code' => '+963', 'country' => 'Syria'], ['code' => '+886', 'country' => 'Taiwan'],
        ['code' => '+992', 'country' => 'Tajikistan'], ['code' => '+255', 'country' => 'Tanzania'],
        ['code' => '+66', 'country' => 'Thailand'], ['code' => '+670', 'country' => 'Timor-Leste'],
        ['code' => '+228', 'country' => 'Togo'], ['code' => '+690', 'country' => 'Tokelau'],
        ['code' => '+676', 'country' => 'Tonga'], ['code' => '+1868', 'country' => 'Trinidad & Tobago'],
        ['code' => '+216', 'country' => 'Tunisia'], ['code' => '+90', 'country' => 'Turkey'],
        ['code' => '+993', 'country' => 'Turkmenistan'], ['code' => '+1649', 'country' => 'Turks & Caicos Islands'],
        ['code' => '+688', 'country' => 'Tuvalu'], ['code' => '+256', 'country' => 'Uganda'],
        ['code' => '+380', 'country' => 'Ukraine'], ['code' => '+971', 'country' => 'United Arab Emirates'],
        ['code' => '+44', 'country' => 'United Kingdom'], ['code' => '+1', 'country' => 'United States'],
        ['code' => '+598', 'country' => 'Uruguay'], ['code' => '+1', 'country' => 'US Virgin Islands'],
        ['code' => '+998', 'country' => 'Uzbekistan'], ['code' => '+678', 'country' => 'Vanuatu'],
        ['code' => '+379', 'country' => 'Vatican City'], ['code' => '+58', 'country' => 'Venezuela'],
        ['code' => '+84', 'country' => 'Vietnam'], ['code' => '+681', 'country' => 'Wallis & Futuna'],
        ['code' => '+967', 'country' => 'Yemen'], ['code' => '+260', 'country' => 'Zambia'],
        ['code' => '+263', 'country' => 'Zimbabwe'],
    ];

    function generateAdvancedPhoneInput($fieldName, $fieldLabel, $fullNumber, $default_prefix) {
        global $prefixes;
        $normalizedPhone = preg_replace('/[\s\(\)\-]+/', '', (string)$fullNumber);
        if (substr($normalizedPhone, 0, 2) === '00') {
            $normalizedPhone = '+' . substr($normalizedPhone, 2);
        }
        $selectedPrefix = '';
        $strippedPhone = $normalizedPhone;
        usort($prefixes, function($a, $b) {
            return strlen($b['code']) - strlen($a['code']);
        });
        foreach ($prefixes as $p) {
            if (strpos($normalizedPhone, $p['code']) === 0) {
                $selectedPrefix = $p['code'];
                $strippedPhone = substr($normalizedPhone, strlen($p['code']));
                break;
            }
        }
        if(empty($fullNumber) && !empty($default_prefix) && $default_prefix != 'no') {
            $selectedPrefix = $default_prefix;
        }
        usort($prefixes, function($a, $b) {
            return strcmp($a['country'], $b['country']);
        });
        ?>
        <div class="form-group">
            <label for="<?php echo htmlspecialchars($fieldName); ?>"><?php echo htmlspecialchars($fieldLabel); ?></label>
            <div class="input-group">
                <select name="<?php echo htmlspecialchars($fieldName); ?>_prefix" id="<?php echo htmlspecialchars($fieldName); ?>_prefix" class="custom-select" style="<?php echo (($default_prefix == 'no') ? 'display: none' : 'flex: 1 1 50%') ?>;">
                    <option value="" <?php if(empty($selectedPrefix)) echo 'selected'; ?>><?php echo _("Select prefix"); ?></option>
                    <?php
                    foreach ($prefixes as $p) {
                        $selected = ($p['code'] === $selectedPrefix) ? 'selected' : '';
                        echo "<option value=\"{$p['code']}\" {$selected}>({$p['code']}) {$p['country']}</option>";
                    }
                    ?>
                </select>
                <input type="tel" name="<?php echo htmlspecialchars($fieldName); ?>" class="form-control" id="<?php echo htmlspecialchars($fieldName); ?>"
                       value="<?php echo ($default_prefix=='no') ? htmlspecialchars($fullNumber) : htmlspecialchars($strippedPhone); ?>" style="flex: 1 1 50%;" />
            </div>
        </div>
        <?php
    }
}

function print_language_input_selector($languages,$default_language,$elem) {
    global $demo,$_SESSION;
    $html = "";
    if(count($languages)>1) {
        $html = '&nbsp;&nbsp;<div data-elem="'.$elem.'" data-default-lang="'.$default_language.'" class="dropdown d-inline-block no-arrow lang_input_switcher">
            <a id="dropdown_lang_'.$elem.'" style="vertical-align:text-bottom" class="dropdown-toggle" href="#" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                <img style="height: 14px;" src="img/flags_lang/'.$default_language.'.png?v=3" />
            </a>';
        switch($elem) {
            case 'default_am_placeholders':
                $html .= '&nbsp;<span onclick="translate_deepl_default_am_placeholders();" class="badge '.(($demo) ? 'disabled_d':'').' badge-primary translate_deepl_btn">'._("translate").' <i class="fas fa-globe"></i></span>';
                break;
            case 'cat_name':
                $html .= '&nbsp;<span onclick="translate_deepl_cats();" class="badge '.(($demo) ? 'disabled_d':'').' badge-primary translate_deepl_btn">'._("translate").' <i class="fas fa-globe"></i></span>';
                break;
            default:
                $html .= '&nbsp;<span onclick="translate_deepl(\''.$elem.'\');" class="badge '.(($demo) ? 'disabled_d':'').' badge-primary translate_deepl_btn">'._("translate").' <i class="fas fa-globe"></i></span>';
                break;
        }
        $html .= '<div style="min-width:330px;" class="dropdown-menu text-center shadow">';
        foreach ($languages as $lang) {
            $html_default = "&nbsp;<i style='opacity:0;pointer-events:none' class='fas fa-circle'></i>";
            if($lang==$default_language) {
                $html_default = "&nbsp;<i class='fas fa-star'></i>";
            }
            $html .= '<span style="cursor:pointer;width:calc(33.33% - 8px);font-weight:normal;" onclick="switch_input_language(\''.$lang.'\',\''.$default_language.'\',\''.$elem.'\',false);" class="lang noselect mx-1 my-1 p-0 d-inline-block align-middle"><img class="mb-1" src="img/flags_lang/'.$lang.'.png"> <span>'.str_replace("_","-",$lang).'</span>'.$html_default.'</span>';
        }
        $html.="</div></div>";
        $html .="<script>
                $( document ).ready(function() {
                    try {
                        var url = new URL(location.href);
                        var url_params = new URLSearchParams(url.search);
                        var page_section = url_params.get('p');
                        var lang = sessionStorage.getItem('lang_".$_SESSION['id_map_sel']."_'+page_section);
                        if(lang!==null) {
                            switch_input_language(lang,'$default_language','$elem');
                        }
                    } catch (e) {}
                });
                </script>";
    }
    return $html;
}

function save_input_langs($array_lang,$table,$id_column,$id) {
    global $mysqli;
    $new_array_lang = array();
    foreach ($array_lang as $key => $values) {
        foreach ($values as $lang => $text) {
            $new_array_lang[$lang][$key] = $text;
        }
    }
    foreach ($new_array_lang as $lang => $values) {
        $columns_array = [];
        $values_array = [];
        $bind_types = "is";
        foreach ($values as $column => $value) {
            $columns_array[] = $column;
            if(empty($value)) $value=null;
            $values_array[] = $value;
            $bind_types .= 's';
        }
        $placeholders = implode(',', array_fill(0, count($columns_array), '?'));
        $sql = "INSERT INTO $table ($id_column, language, " . implode(",", $columns_array) . ") VALUES (?,?,$placeholders)
                        ON DUPLICATE KEY UPDATE ";
        foreach ($columns_array as $column) {
            $sql .= "$column = VALUES($column),";
        }
        $sql = rtrim($sql,",");
        $smt = $mysqli->prepare($sql);
        if($smt) {
            $bind_params = array_merge([$id, $lang], $values_array);
            $smt->bind_param($bind_types, ...$bind_params);
            $smt->execute();
        }
    }
}

function get_languages_showcase() {
    global $showcase,$settings;
    $count_languages_enabled = 0;
    foreach ($showcase['languages_enabled'] as $lang_enabled) {
        if($lang_enabled==1) {
            $count_languages_enabled++;
        }
    }
    $default_language = $showcase['language'];
    if(empty($default_language)) {
        $default_language = $settings['language'];
    }
    if($count_languages_enabled>0) {
        if(array_key_exists($default_language,$showcase['languages_enabled'])) {
            $showcase['languages_enabled'][$default_language]=1;
        }
    }
    $array_languages = array();
    foreach ($showcase['languages_enabled'] as $lang=>$enabled) {
        if($enabled==1) {
            array_push($array_languages,$lang);
        }
    }
    return [$array_languages,$default_language];
}

function set_am_field_checked($key, $categoryFields, $defaultFields) {
    if (array_key_exists($key, $categoryFields)) {
        return ($categoryFields[$key] == 1) ? 'checked' : '';
    }
    if (array_key_exists($key, $defaultFields)) {
        return ($defaultFields[$key] == 1) ? 'checked' : '';
    }
    return 'checked';
}

function format_address_string($data, $format_settings) {
    $address_parts = [];
    foreach ($format_settings as $item) {
        $key = $item['field'];
        $isEnabled = isset($item['enabled']) ? (bool)$item['enabled'] : true;
        if ($isEnabled && !empty($data[$key])) {
            $address_parts[] = $data[$key];
        }
    }

    return implode(', ', $address_parts);
}

function sml_allowed_user_roles() {
    return array('administrator','editor','customer','visitor');
}

function sml_backend_user_roles() {
    return array('administrator','editor','customer');
}

function sml_is_valid_user_role($role) {
    return in_array($role, sml_allowed_user_roles(), true);
}

function sml_is_backend_user_role($role) {
    return in_array($role, sml_backend_user_roles(), true);
}

function sml_cookie_secure() {
    return (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || (!empty($_SERVER['SERVER_PORT']) && (int)$_SERVER['SERVER_PORT'] === 443);
}

function sml_set_auth_cookie($name, $value, $expires) {
    setcookie($name, $value, array(
        'expires' => $expires,
        'path' => '/',
        'secure' => sml_cookie_secure(),
        'httponly' => true,
        'samesite' => 'Lax'
    ));
}

function sml_clear_auth_cookie($name) {
    sml_set_auth_cookie($name, '', time() - 3600);
    unset($_COOKIE[$name]);
}

function sml_get_user_by_username_password($username, $password) {
    global $mysqli;
    require_once(__DIR__."/../config/config.inc.php");
    $key_enc = PASSWORDS_ENCRYPT_KEY;
    $query = "SELECT * FROM sml_users WHERE (username=? OR email=?) AND password=AES_ENCRYPT(?, ?) LIMIT 1;";
    if($smt = $mysqli->prepare($query)) {
        $smt->bind_param('ssss',$username,$username,$password,$key_enc);
        if($smt->execute()) {
            $result = get_result($smt);
            if(count($result)==1) {
                return array_shift($result);
            }
        }
    }
    return false;
}

function sml_get_active_user($id_user) {
    global $mysqli;
    $id_user = (int)$id_user;
    $query = "SELECT id,username,email,role,active,language FROM sml_users WHERE id=? AND active=1 LIMIT 1;";
    if($smt = $mysqli->prepare($query)) {
        $smt->bind_param('i',$id_user);
        if($smt->execute()) {
            $result = get_result($smt);
            if(count($result)==1) {
                return array_shift($result);
            }
        }
    }
    return false;
}

function sml_username_exists($username, $exclude_id = 0) {
    global $mysqli;
    $exclude_id = (int)$exclude_id;
    if($exclude_id>0) {
        $query = "SELECT id FROM sml_users WHERE username=? AND id<>? LIMIT 1;";
        if($smt = $mysqli->prepare($query)) {
            $smt->bind_param('si',$username,$exclude_id);
            $smt->execute();
            $result = get_result($smt);
            return count($result)>0;
        }
    } else {
        $query = "SELECT id FROM sml_users WHERE username=? LIMIT 1;";
        if($smt = $mysqli->prepare($query)) {
            $smt->bind_param('s',$username);
            $smt->execute();
            $result = get_result($smt);
            return count($result)>0;
        }
    }
    return false;
}

function sml_email_exists($email, $exclude_id = 0) {
    global $mysqli;
    if($email===null) return false;
    $email = trim($email);
    if($email==='') return false;
    $exclude_id = (int)$exclude_id;
    if($exclude_id>0) {
        $query = "SELECT id FROM sml_users WHERE email=? AND id<>? LIMIT 1;";
        if($smt = $mysqli->prepare($query)) {
            $smt->bind_param('si',$email,$exclude_id);
            $smt->execute();
            $result = get_result($smt);
            return count($result)>0;
        }
    } else {
        $query = "SELECT id FROM sml_users WHERE email=? LIMIT 1;";
        if($smt = $mysqli->prepare($query)) {
            $smt->bind_param('s',$email);
            $smt->execute();
            $result = get_result($smt);
            return count($result)>0;
        }
    }
    return false;
}

function sml_issue_viewer_remember_token($id_user) {
    global $mysqli;
    $id_user = (int)$id_user;
    $selector = bin2hex(random_bytes(16));
    $validator = bin2hex(random_bytes(32));
    $validator_hash = hash('sha256',$validator);
    $created_at = date('Y-m-d H:i:s');
    $expires_at = date('Y-m-d H:i:s', time() + (30 * 24 * 60 * 60));
    $query = "INSERT INTO sml_remember_tokens(id_user,selector,validator_hash,expires_at,created_at) VALUES(?,?,?,?,?);";
    if($smt = $mysqli->prepare($query)) {
        $smt->bind_param('issss',$id_user,$selector,$validator_hash,$expires_at,$created_at);
        if($smt->execute()) {
            sml_set_auth_cookie('sml_viewer_remember',$selector.':'.$validator,time() + (30 * 24 * 60 * 60));
            return true;
        }
    }
    return false;
}

function sml_clear_viewer_remember_token() {
    global $mysqli;
    if(isset($_COOKIE['sml_viewer_remember'])) {
        $parts = explode(':', $_COOKIE['sml_viewer_remember'], 2);
        if(count($parts)==2) {
            $selector = $parts[0];
            $query = "DELETE FROM sml_remember_tokens WHERE selector=?;";
            if($smt = $mysqli->prepare($query)) {
                $smt->bind_param('s',$selector);
                $smt->execute();
            }
        }
    }
    sml_clear_auth_cookie('sml_viewer_remember');
}

function sml_viewer_user_from_remember_token() {
    global $mysqli;
    if(empty($_COOKIE['sml_viewer_remember'])) {
        return false;
    }
    $parts = explode(':', $_COOKIE['sml_viewer_remember'], 2);
    if(count($parts)!=2) {
        sml_clear_viewer_remember_token();
        return false;
    }
    $selector = $parts[0];
    $validator = $parts[1];
    $now = date('Y-m-d H:i:s');
    $query = "SELECT t.id,t.id_user,t.validator_hash,u.username,u.email,u.role,u.active,u.language FROM sml_remember_tokens t INNER JOIN sml_users u ON u.id=t.id_user WHERE t.selector=? AND t.expires_at>? LIMIT 1;";
    if($smt = $mysqli->prepare($query)) {
        $smt->bind_param('ss',$selector,$now);
        if($smt->execute()) {
            $result = get_result($smt);
            if(count($result)==1) {
                $row = array_shift($result);
                if(hash_equals($row['validator_hash'], hash('sha256',$validator)) && $row['active'] && sml_is_valid_user_role($row['role'])) {
                    $id_token = (int)$row['id'];
                    $last_used_at = date('Y-m-d H:i:s');
                    $mysqli->query("UPDATE sml_remember_tokens SET last_used_at='$last_used_at' WHERE id=$id_token;");
                    $_SESSION['viewer_id_user'] = (int)$row['id_user'];
                    return array('id'=>(int)$row['id_user'],'username'=>$row['username'],'email'=>$row['email'],'role'=>$row['role'],'active'=>$row['active'],'language'=>$row['language']);
                }
            }
        }
    }
    sml_clear_viewer_remember_token();
    return false;
}

function sml_get_viewer_user() {
    if(!empty($_SESSION['viewer_id_user'])) {
        $user = sml_get_active_user($_SESSION['viewer_id_user']);
        if($user!==false) {
            return $user;
        }
        unset($_SESSION['viewer_id_user']);
    }
    return sml_viewer_user_from_remember_token();
}

function sml_get_viewer_user_id() {
    $user = sml_get_viewer_user();
    if($user!==false) {
        return (int)$user['id'];
    }
    return null;
}

function sml_get_viewer_auth_settings($id_map) {
    global $mysqli;
    $id_map = (int)$id_map;
    $defaults = array(
        'viewer_auth_mode'=>0,
        'add_marker_require_login'=>0,
        'review_require_login'=>0,
        'add_photo_require_login'=>0,
        'issue_report_require_login'=>0,
        'live_tracking_require_login'=>0,
        'enable_add_marker'=>0,
        'enable_reviews'=>1,
        'enable_add_photo'=>0,
        'enable_issue_reports'=>1,
        'live_tracking'=>0
    );
    $query = "SELECT viewer_auth_mode,add_marker_require_login,review_require_login,add_photo_require_login,issue_report_require_login,live_tracking_require_login,enable_add_marker,enable_reviews,enable_add_photo,enable_issue_reports,live_tracking FROM sml_maps WHERE id=? LIMIT 1;";
    if($smt = $mysqli->prepare($query)) {
        $smt->bind_param('i',$id_map);
        if($smt->execute()) {
            $result = get_result($smt);
            if(count($result)==1) {
                return array_merge($defaults,array_shift($result));
            }
        }
    }
    return $defaults;
}

function sml_generate_random_string($length = 16) {
    $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $return = '';
    for($i=0;$i<$length;$i++) {
        $return .= $characters[random_int(0, strlen($characters) - 1)];
    }
    return $return;
}

function sml_send_mail($email, $subject, $body, $settings = null) {
    if($settings===null) {
        $settings = get_settings();
    }
    if(empty($settings['smtp_server']) || empty($settings['smtp_from_email'])) {
        return false;
    }
    if(!class_exists('\PHPMailer\PHPMailer\PHPMailer')) {
        require_once(__DIR__.'/vendor/PHPMailer/Exception.php');
        require_once(__DIR__.'/vendor/PHPMailer/PHPMailer.php');
        require_once(__DIR__.'/vendor/PHPMailer/SMTP.php');
    }
    $mail = new \PHPMailer\PHPMailer\PHPMailer(true);
    $body = str_replace('<p><br></p>','<br>',$body);
    $body = str_replace('<p>','<p style="padding:0;margin:0;">',$body);
    try {
        $mail->isSMTP();
        $mail->CharSet = 'UTF-8';
        $mail->Timeout = 10;
        $mail->Host = $settings['smtp_server'];
        $mail->SMTPAuth = $settings['smtp_auth'];
        $mail->SMTPOptions = array(
            'ssl' => array(
                'verify_peer' => false,
                'verify_peer_name' => false,
                'allow_self_signed' => true
            )
        );
        $mail->Username = $settings['smtp_username'];
        $mail->Password = $settings['smtp_password'];
        switch($settings['smtp_secure']) {
            case 'ssl':
                $mail->SMTPSecure = \PHPMailer\PHPMailer\PHPMailer::ENCRYPTION_SMTPS;
                break;
            case 'tls':
                $mail->SMTPSecure = \PHPMailer\PHPMailer\PHPMailer::ENCRYPTION_STARTTLS;
                break;
        }
        $mail->Port = $settings['smtp_port'];
        $mail->setFrom($settings['smtp_from_email'], $settings['smtp_from_name']);
        $mail->addAddress($email);
        $mail->isHTML(true);
        $mail->Subject = $subject;
        $mail->Body = $body;
        $mail->send();
        return true;
    } catch (\Exception $e) {
        return false;
    }
}

function sml_absolute_viewer_url($path) {
    $hostName = $_SERVER['HTTP_HOST'];
    if (is_ssl()) { $protocol = 'https'; } else { $protocol = 'http'; }
    $dirname = str_replace('\\','/',dirname($_SERVER['PHP_SELF']));
    $dirname = str_replace('/ajax','',$dirname);
    return $protocol.'://'.$hostName.$dirname.'/'.$path;
}

function sml_send_activation_email($id_user, $id_map, $hash) {
    global $mysqli;
    $settings = get_settings();
    if(empty($settings['smtp_valid'])) {
        return false;
    }
    $query = "SELECT u.username,u.email,m.code FROM sml_users as u, sml_maps as m WHERE u.id=? AND m.id=? LIMIT 1;";
    if($smt = $mysqli->prepare($query)) {
        $smt->bind_param('ii',$id_user,$id_map);
        if($smt->execute()) {
            $result = get_result($smt);
            if(count($result)==1) {
                $row = array_shift($result);
                $url = sml_absolute_viewer_url('validate_email.php?code='.urlencode($row['code']).'&email='.urlencode($row['email']).'&hash='.urlencode($hash));
                $body = $settings['mail_activate_body'];
                $body = str_replace("%LINK%","<a href='$url'>$url</a>",$body);
                $body = str_replace("%USER_NAME%",$row['username'],$body);
                return sml_send_mail($row['email'],$settings['mail_activate_subject'],$body,$settings);
            }
        }
    }
    return false;
}

function sml_send_admin_notification($type, $data = array()) {
    global $mysqli;
    $settings = get_settings();
    if(empty($settings['smtp_valid'])) {
        return false;
    }
    $toggle = '';
    switch($type) {
        case 'marker':
            $toggle = 'notify_marker_to_validate';
            break;
        case 'review':
            $toggle = 'notify_review';
            break;
        case 'issue_report':
            $toggle = 'notify_issue_report';
            break;
        case 'photo':
            $toggle = 'notify_photo_to_validate';
            break;
    }
    if(empty($toggle) || empty($settings[$toggle])) {
        return false;
    }
    $email = trim($settings['notify_email']);
    if(empty($email)) {
        $email = trim($settings['smtp_from_email']);
    }
    if(empty($email)) {
        return false;
    }
    $id_marker = isset($data['id_marker']) ? (int)$data['id_marker'] : 0;
    $marker = array('marker_name'=>'','map_name'=>'','street'=>'','city'=>'','country'=>'','lat'=>'','lon'=>'');
    if($id_marker>0) {
        $query = "SELECT m.name as marker_name,m.street,m.city,m.country,m.lat,m.lon,mp.name as map_name FROM sml_markers as m LEFT JOIN sml_maps as mp ON mp.id=m.id_map WHERE m.id=? LIMIT 1;";
        if($smt = $mysqli->prepare($query)) {
            $smt->bind_param('i',$id_marker);
            if($smt->execute()) {
                $result = get_result($smt);
                if(count($result)==1) {
                    $marker = array_merge($marker,array_shift($result));
                }
            }
        }
    }
    $app_name = $settings['name'];
    $marker_name = htmlspecialchars($marker['marker_name']);
    $map_name = htmlspecialchars($marker['map_name']);
    $where = trim($marker['street'].' '.$marker['city'].' '.$marker['country']);
    if(empty($where)) {
        $where = trim($marker['lat'].', '.$marker['lon'],', ');
    }
    $where = htmlspecialchars($where);
    switch($type) {
        case 'marker':
            $subject = $app_name.' - New marker pending validation';
            $body = '<p>A new marker has been added and is waiting for validation.</p><p>Map: '.$map_name.'<br>Marker: '.$marker_name.'<br>Location: '.$where.'</p>';
            break;
        case 'review':
            $subject = $app_name.' - New marker review';
            $body = '<p>A new review has been added to a marker.</p><p>Map: '.$map_name.'<br>Marker: '.$marker_name.'<br>Name: '.htmlspecialchars($data['name']).'<br>E-mail: '.htmlspecialchars($data['email']).'<br>Rating: '.htmlspecialchars($data['rating']).'<br>Comment: '.nl2br(htmlspecialchars($data['comment'])).'</p>';
            break;
        case 'issue_report':
            $subject = $app_name.' - New issue report';
            $body = '<p>A new issue report has been submitted.</p><p>Map: '.$map_name.'<br>Marker: '.$marker_name.'<br>Name: '.htmlspecialchars($data['name']).'<br>E-mail: '.htmlspecialchars($data['email']).'<br>Comment: '.nl2br(htmlspecialchars($data['comment'])).'</p>';
            break;
        case 'photo':
            $subject = $app_name.' - New photo pending validation';
            $body = '<p>A new photo has been added to a marker and is waiting for validation.</p><p>Map: '.$map_name.'<br>Marker: '.$marker_name.'<br>Name: '.htmlspecialchars($data['name']).'<br>E-mail: '.htmlspecialchars($data['email']).'<br>Photo: '.htmlspecialchars($data['photo']).'</p>';
            break;
        default:
            return false;
    }
    return sml_send_mail($email,$subject,$body,$settings);
}

function sml_viewer_feature_requires_login($id_map, $feature) {
    $settings = sml_get_viewer_auth_settings($id_map);
    if((int)$settings['viewer_auth_mode']<=0) {
        return false;
    }
    $field = $feature.'_require_login';
    return !empty($settings[$field]);
}

function sml_viewer_can_use_feature($id_map, $feature) {
    if(!sml_viewer_feature_requires_login($id_map,$feature)) {
        return true;
    }
    return sml_get_viewer_user_id()!==null;
}

function get_all_map_media_files($id_map) {
    global $mysqli;
    $files_map = array();
    if (empty($id_map)) {
        $query = "SELECT id, file, id_map FROM sml_media_library WHERE $id_map IS NULL ORDER BY id DESC;";
    } else {
        $query = "SELECT id, file, id_map FROM sml_media_library WHERE id_map=$id_map OR id_map IS NULL ORDER BY id DESC;";
    }
    $result = $mysqli->query($query);
    if ($result && $result->num_rows > 0) {
        while ($row = $result->fetch_array(MYSQLI_ASSOC)) {
            $row['from'] = 'media_library';
            if (empty($row['id_map'])) $row['id_map'] = '';
            $path_file = __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'viewer' . DIRECTORY_SEPARATOR . 'media' . DIRECTORY_SEPARATOR . $row['file'];
            if (file_exists($path_file)) {
                $row['count'] = 0;
                $files_map[$row['file']] = $row;
            }
        }
    }
    $query = "SELECT 0 as id,image as file FROM sml_images WHERE id_marker IN (SELECT id FROM sml_markers WHERE id_map=$id_map) ORDER BY id DESC;";
    $result = $mysqli->query($query);
    if ($result && $result->num_rows > 0) {
        while ($row = $result->fetch_array(MYSQLI_ASSOC)) {
            $row['from'] = 'marker_images';
            $clean_filename = $row['file'];
            $path_file = __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'viewer' . DIRECTORY_SEPARATOR . 'marker_images' . DIRECTORY_SEPARATOR . $clean_filename;
            if (file_exists($path_file)) {
                if (isset($files_map[$clean_filename])) {
                    $files_map[$clean_filename]['count']++;
                } else {
                    $row['file'] = $clean_filename;
                    $row['count'] = 1;
                    $files_map[$clean_filename] = $row;
                }
            }
        }
    }
    return array_values($files_map);
}

function slugify($string) {
    $string = iconv('UTF-8', 'ASCII//TRANSLIT', $string);
    $string = strtolower($string);
    $string = preg_replace('/[^a-z0-9\s-]/', '', $string);
    $string = preg_replace('/[\s-]+/', '-', $string);
    return trim($string, '-');
}

function isa_convert_bytes_to_specified_d($bytes, $to, $decimal_places = 1) {
    $formulas = array(
            'K' => number_format($bytes / 1024, $decimal_places,'.',''),
            'M' => number_format($bytes / 1048576, $decimal_places,'.',''),
            'G' => number_format($bytes / 1099511627776, $decimal_places,'.','')
    );
    return isset($formulas[$to]) ? $formulas[$to] : 0;
}

function _GetMaxAllowedUploadSize(){
    $Sizes = array();
    $Sizes[] = ini_get('upload_max_filesize');
    $Sizes[] = ini_get('post_max_size');
    $Sizes[] = ini_get('memory_limit');
    for($x=0;$x<count($Sizes);$x++){
        $Last = strtolower($Sizes[$x][strlen($Sizes[$x])-1]);
        if($Last == 'k'){
            $Sizes[$x] *= 1024;
        } elseif($Last == 'm'){
            $Sizes[$x] *= 1024;
            $Sizes[$x] *= 1024;
        } elseif($Last == 'g'){
            $Sizes[$x] *= 1024;
            $Sizes[$x] *= 1024;
            $Sizes[$x] *= 1024;
        } elseif($Last == 't'){
            $Sizes[$x] *= 1024;
            $Sizes[$x] *= 1024;
            $Sizes[$x] *= 1024;
            $Sizes[$x] *= 1024;
        }
    }
    return isa_convert_bytes_to_specified_d(min($Sizes),'M',0);
}
