<?php
/**
 * @package    JBusinessDirectory
 *
 * @author CMSJunkie http://www.cmsjunkie.com
 * @copyright  Copyright (C) 2007 - 2021 CMSJunkie. All rights reserved.
 * @license   https://www.gnu.org/licenses/agpl-3.0.en.html
 */

use Joomla\CMS\Factory;
use Joomla\CMS\HTML\HTMLHelper;

/**
 * JBD utility class
 *
 *
 * @author George
 *
 */
class JBusinessUtil {
	public $applicationSettings ;

	private function __construct() {
	}

	/**
	 * Singletion function for retrieving the unique instance
	 *
	 * @return JBusinessUtil
	 */
	public static function getInstance() {
		static $instance;
		if ($instance === null) {
			$instance = new JBusinessUtil();
		}
		return $instance;
	}

	/**
	 * Retrieve the application setting instance
	 *
	 * @return stdClass application settings
	 */
	public static function getApplicationSettings() {
		$instance = JBusinessUtil::getInstance();

		if (!isset($instance->applicationSettings)) {
			$instance->applicationSettings = self::getAppSettings();
		}
		return $instance->applicationSettings;
	}

	/**
	 * Get the general settings from the database
	 *
	 * @return stdClass app settings
	 */
	private static function getAppSettings() {
		$db		= JFactory::getDBO();
		$query	= "	SELECT fas.*
	                  FROM #__jbusinessdirectory_application_settings fas";

		//dump($query);
		$db->setQuery($query);
		$appSettings =  $db->loadObjectList();
		
		$app = new stdClass();
		foreach ($appSettings as $setting) {
			$app->{$setting->name} = $setting->value;
		}

		$query	= "SELECT fas.*
	                  FROM #__jbusinessdirectory_date_formats fas
	                WHERE fas.id ='".$app->date_format_id."'" ;
		$db->setQuery($query);
		$date =  $db->loadObject();
		foreach ($date as $key=>$item) {
			$app->{$key} = $item;
		}

		$query	= "SELECT fas.*
	                  FROM #__jbusinessdirectory_currencies fas
	                WHERE fas.currency_id ='".$app->currency_id."'" ;
		$db->setQuery($query);
		$date =  $db->loadObject();
		foreach ($date as $key=>$item) {
			if ($key=="currency_symbol" && !empty($app->currency_symbol)) {
				continue;
			}
				
			$app->{$key} = $item;
		}

		$app->url_fields = explode(",", $app->url_fields);
		$app->search_categories = explode(",", $app->search_categories);
		
		if (!empty($app->marker_size)) {
			$size = explode(';', $app->marker_size);
			$tmp = new stdClass();
			$tmp->width = $size[0];
			$tmp->height = $size[1];

			$app->marker_size = $tmp;
		}

		$app->vat_configuration = json_decode($app->vat_config);

		return $app;
	}

	/**
	 * Retrieve a property
	 *
	 * @param [type] $prop
	 * @return void
	 */
	public static function getProperty($prop, $default=null) {
		$instance = JBusinessUtil::getInstance();

		if (!isset($instance->properties)) {
			$instance->properties = self::loadProperties();
		}

		if(isset($instance->properties[$prop])){
			return $instance->properties[$prop];
		}else{
			return $default;
		}

	}

	/**
	 * Set a property
	 * 
	 */
	public static function setProperty($prop, $value) {
		$db	= JFactory::getDBO();
		
		$query = "insert into #__jbusinessdirectory_properties(name, value) values ('$prop', '$value')";
		$query = $query." ON DUPLICATE KEY UPDATE `value`=values(`value`)"; 
		
		$db->setQuery($query);
		
		if (!$db->execute()) {
			echo 'INSERT / UPDATE sql STATEMENT error !';
			return false;
		} 

		$instance = JBusinessUtil::getInstance();
		if (isset($instance->properties)) {
			$instance->properties[$prop] = $value;
		}

		return true;
	}

	/**
	 * Load the properties from the database
	 * 
	 *
	 * @return void
	 */
	private static function loadProperties() {
		$db		= JFactory::getDBO();
		$query	= "SELECT * FROM #__jbusinessdirectory_properties" ;
		
		$db->setQuery($query);
		$result = array();
		$properties =  $db->loadObjectList();
		foreach ($properties as $prop) {
			$result[$prop->name] = $prop->value;
		}

		$instance = JBusinessUtil::getInstance();
		$instance->properties = $result;
	}


	/**
	 * Retrieve the site configs
	 *
	 * @return JConfig
	 */
	public static function getSiteConfig() {
		$config = new JConfig();
		
		/*  $config->mailfrom ="";
		$config->fromname ="";
		$config->tmp_path = "";
		$config->sitename ="";
		 */
		return $config;
	}
	
	/**
	 * Set page meta data based on the following parameters
	 *
	 * @param $title string page title
	 * @param $description string site description
	 * @param $keywords string site keywords
	 * @param $useMenuParams boolean menu params
	 * @return boolean
	 */
	public static function setMetaData($title, $description, $keywords, $useMenuParams = false) {
		$document = JFactory::getDocument();
		$config = self::getSiteConfig();
		$app = JFactory::getApplication();
		$appSettings = JBusinessUtil::getApplicationSettings();

		if ($useMenuParams) {
			//retrieving current menu item parameters
			$activeMenu = JFactory::getApplication()->getMenu()->getActive();
			if (isset($activeMenu)) {
				$params = new JRegistry();
				if (isset($activeMenu)) {
					$params = $activeMenu->getParams();
				}
				$metaTitle = "";
				//set page title
				if (!empty($params) && $params->get('page_title') != '') {
					$metaTitle = $params->get('page_title', '');
				}
				if (empty($metaTitle)) {
					$metaTitle = $title;
				}
				
				//set page meta description and keywords
				if (empty($description)) {
					$description = $appSettings->meta_description;
				}
				
				$kwords = $appSettings->meta_keywords;
				if(!empty($keywords)){
					$kwords = $keywords;
				}

				$document->setTitle($title);
				$document->setDescription($description);
				$document->setMetadata('keywords', $kwords);
			  
				if (!empty($params) && $params->get('menu-meta_description')) {
					$document->setDescription('description', $params->get('menu-meta_description'));
				}
			   
				if (!empty($params) && $params->get('menu-meta_keywords')) {
					$document->setMetadata('keywords', $params->get('menu-meta_keywords'));
				}
				
				if (!empty($params) && $params->get('robots')) {
					$document->setMetadata('robots', $params->get('robots'));
				}
			}
		} else {
			if ($title) {
				$document->setTitle($title);
			}
			
			if ($description) {
				$document->setDescription($description);
			}
			
			if ($keywords) {
				$document->setMetadata('keywords', $keywords);
			}
		}
		
		return true;
	}
	
	/**
	 * Set Facebook meta data
	 *
	 * @param $title string title meta
	 * @param $description string description
	 * @param $logo string logo
	 * @param $url string url
	 * @return boolean true when finished with success
	 */
	public static function setFacebookMetaData($title, $description, $logo, $url) {
		$document = JFactory::getDocument();
		$config = self::getSiteConfig();

		$document->addCustomTag('<meta property="og:title" content="'.$title.'"/>');
		$document->addCustomTag('<meta property="og:description" content="'.$description.'"/>');
		
		if (!empty($logo)) {
			$document->addCustomTag('<meta property="og:image" content="'.BD_PICTURES_PATH.$logo.'" /> ');
		}
		$document->addCustomTag('<meta property="og:type" content="website"/>');
		$document->addCustomTag('<meta property="og:url" content="'.$url.'"/>');
		$document->addCustomTag('<meta property="og:site_name" content="'.$config->sitename.'"/>');
		
		return true;
	}

	/**
	 * Set canonical URL
	 *
	 * @param $url string url
	 * @return boolean true when finished with success
	 */
	public static function setCanonicalURL($url) {
		$document = JFactory::getDocument();

		//reset the previous canonical tag
		foreach ($document->_links as $key=> $value) {
			if (is_array($value)) {
				//dump($value);
				if (array_key_exists('relation', $value)) {
					if ($value['relation'] == 'canonical') {
						//the document link that contains the canonical url found and changed
						$document->_links[$url] = $value;
						unset($document->_links[$key]);
						break;
					}
				}
			}
		}
		
		//add the new canonical link
		$document->addHeadLink(htmlspecialchars($url), 'canonical');
		return true;
	}

	/**
	 * Retrieve the current editor
	 *
	 * @return \Joomla\CMS\Editor\Editor|string
	 */
	public static function getEditor() {
		if (defined('JVERSION')) {
			$joomlaVersion = (int) JVERSION;
		} else {
			$j = new JVersion();
			$joomlaVersion = (int) $j->getShortVersion();
		}
		
		if ($joomlaVersion == 3) {
			$editor = JFactory::getEditor();
		} else {
			$editor = self::getSiteConfig()->editor;
			$editor = JEditor::getInstance($editor);
		}
		
		return $editor;
	}

	/**
	 * Retrieve the current user or an user by id
	 *
	 * @param $id int id of the user if needed specific user
	 * @return \Joomla\CMS\User\User|null
	 */
	public static function getUser($id=null) {
		$user = null;
		if (isset($id)) {
			$user = JFactory::getUser($id);
		} else {
			$user = JFactory::getUser();
		}
		
		return $user;
	}

	/**
	 * Generate the menu parameter based on the active menu item
	 *
	 * @return string menu item
	 * @throws Exception
	 */
	public static function getActiveMenuItem() {
		$appSettings = JBusinessUtil::getApplicationSettings();
		
		$activeMenu = JFactory::getApplication()->getMenu()->getActive();
		$menuItem="";
		if (isset($activeMenu)) {
			$menuItem="&Itemid=".$activeMenu->id;
		} elseif (!empty($appSettings->menu_item_id)) {
			$menuItem = "&Itemid=".$appSettings->menu_item_id;
		}
		
		return $menuItem;
	}


	/**
	 * Retrieve the page title based on the menu item settings
	 * 
	 * @param unknown $defaultTitle
	 * @return unknown
	 */
	public static function getPageTitle($defaultTitle){
		$activeMenu = JFactory::getApplication()->getMenu()->getActive();
		if (isset($activeMenu)) {
			$menuitem = JFactory::getApplication()->getMenu()->getItem($activeMenu->id);
			$params = $menuitem->getParams();
			
			//set page title
			if(!empty($params) && $params->get('page_title') != '' ) {
				$title = $params->get('page_title', '');
				return $title;
			}
		}
		
		return $defaultTitle;
	}
	
	/**
	 * Check if a user has access to a certain view
	 *
	 * @param $permission string permision that need to be checked
	 * @param $view string view to check in
	 * @throws Exception
	 */
	public static function checkPermissions($permission, $view) {
		$menuItemId = self::getActiveMenuItem();
		$appSettings = self::getApplicationSettings();
		
		$user = JBusinessUtil::getUser();
		if ($user->id == 0) {
			$app = JFactory::getApplication();
			$return = base64_encode(("index.php?option=com_jbusinessdirectory&view=$view".$menuItemId));
			$app->redirect('index.php?option=com_users&view=login&return='.$return.$menuItemId);
		}
		
		$actions = JBusinessDirectoryHelper::getActions();
		
		if (!$actions->get($permission) && $appSettings->front_end_acl) {
			$app = JFactory::getApplication();
			if($view != "useroptions"){
				$app->redirect(JRoute::_('index.php?option=com_jbusinessdirectory&view=useroptions', false), JText::_("LNG_ACCESS_RESTRICTED"), "warning");
			}else{
				$app->redirect(JRoute::_('index.php?option=com_jbusinessdirectory&view=userdashboard', false));
			}
		}
	}

	/**
	 * Include script files
	 * @param $file string path of the file to include
	 */
	public static function enqueueScript($file) {
		JHTML::_('script', BD_ASSETS_FOLDER_PATH.$file);
	}

	/**
	 * Include css files
	 *
	 * @param $file string path of the file to include
	 */
	public static function enqueueStyle($file) {
		JHTML::_('stylesheet', BD_ASSETS_FOLDER_PATH.$file);
	}

	/**
	 * Include the default css libraries
	 */
	public static function includeCSSLibraries() {
		JBusinessUtil::enqueueStyle('css/jbd-style.css');
		JBusinessUtil::enqueueStyle('css/common.css');

		if(file_exists(JPATH_SITE . '/components/com_jbusinessdirectory/assets/css/custom.css')){
			JBusinessUtil::enqueueStyle('css/custom.css');
		}

		JBusinessUtil::enqueueStyle('css/line-awesome.css');

		$appSettings = self::getApplicationSettings();
		if ($appSettings->image_display==2) {
			$document = JFactory::getDocument();
			// Add styles
			$style = '.jbd-container .jitem-card img, .jbd-container .place-card img { object-fit: contain !important; }';
			$document->addStyleDeclaration($style);
		}
		
		
		if (defined('JVERSION')) {
			$joomlaVersion = (int) JVERSION;
		} else {
			$j = new JVersion();
			$joomlaVersion = (int) $j->getShortVersion();
		}
		
	//
			JBusinessUtil::enqueueStyle('css/jbd-style_v3.css');
		if ($joomlaVersion == 4) {
			JBusinessUtil::enqueueStyle('css/jbd-style_v4.css');
		}
	}

	/**
	 * Sanize all request variables
	 *
	 * @throws Exception
	 */
	public static function sanitizeRequest() {
		$jinput = JFactory::getApplication()->input;
		
		$params = $_REQUEST;
		foreach ($params as $name=>$value) {
			if (strpos($name, "description")===false) {
				$value= str_replace('"', "", $value);
				$jinput->set($name, $value);
			}
		}
	}

	/**
	 * Load all available classes on classes folder
	 */
	public static function loadClasses() {
		jimport('joomla.filesystem.file');
		jimport('joomla.filesystem.folder');

		//load payment processors
		$classpath = BD_CLASSES_PATH.DS.'payment'.DS.'processors';
		foreach (JFolder::files($classpath) as $file) {
			JLoader::register(JFile::stripExt($file), $classpath.DS.$file);
		}

		//load payment processors
		$classpath = BD_CLASSES_PATH.DS.'payment';
		foreach (JFolder::files($classpath) as $file) {
			JLoader::register(JFile::stripExt($file), $classpath.DS.$file);
		}

		//load services
		$classpath = BD_CLASSES_PATH.DS.'services';
		foreach (JFolder::files($classpath) as $file) {
			JLoader::register(JFile::stripExt($file), $classpath.DS.$file);
		}

		//load elasticsearch
		$classpath = BD_CLASSES_PATH.DS.'elasticsearch';
		if(file_exists($classpath)){
			foreach (JFolder::files($classpath) as $file) {
				JLoader::register(JFile::stripExt($file), $classpath.DS.$file);
			}
		}

		$classpath = BD_CLASSES_PATH.DS.'elasticsearch'.DS.'indexer';
		if(file_exists($classpath)){
			foreach (JFolder::files($classpath) as $file) {
				JLoader::register(JFile::stripExt($file), $classpath.DS.$file);
			}
		}

	}

	/**
	 * Retrieve the data from a specific URL based on curl
	 *
	 * @param $url string url that need to get the data from
	 * @return bool|string
	 */
	public static function getURLData($url) {
		$ch = curl_init();
		$timeout = 5;
		curl_setopt($ch, CURLOPT_URL, $url);
		curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0)");
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
		curl_setopt($ch, CURLOPT_MAXREDIRS, 10);
		//curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
		curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
		$data = curl_exec($ch);
		curl_close($ch);
		return $data;
	}

	/**
	 * Translated the zip code to map coordinates based on Google geolocation
	 *
	 * @param $zipCode string zip code
	 * @return array|null array with lat and lang or nothing if any error accour
	 */
	public static function getCoordinates($zipCode) {
		$appSettings = JBusinessUtil::getApplicationSettings();
		$mapType = $appSettings->map_type;

		$limitCountries = array();
		$location = null;

		if (!empty($appSettings->country_ids)) {
			$countryIDs = explode(",", $appSettings->country_ids);

			foreach ($countryIDs as $countryID) {
				$country = self::getCountry($countryID);
				array_push($limitCountries, $country->country_code);
			}
		}

		$countryParam = "";
		if (!empty($limitCountries)) {
			if ($mapType == MAP_TYPE_GOOGLE) {
				$countries = array();
				foreach ($limitCountries as $country) {
					$countries[]="country:".$country;
				}

				$countries = implode("|", $countries);
				$countryParam ="&components=".$countries;
			} elseif ($mapType == MAP_TYPE_OSM) {
				$countryParam = "&countrycodes=".implode(',', $limitCountries);
			}
		}

		$key="";
		if (!empty($appSettings->google_map_key)) {
			$key="&key=".$appSettings->google_map_key;
			if (!empty($appSettings->google_map_key_zipcode)) {
				$key="&key=".$appSettings->google_map_key_zipcode;
			}
		}

		$url ="https://maps.googleapis.com/maps/api/geocode/json?sensor=false$key$countryParam&address=".urlencode($zipCode);

		if ($mapType == MAP_TYPE_OSM) {
			$url = "https://nominatim.openstreetmap.org/search?format=json&addressdetails=1&q=".urlencode($zipCode).$countryParam;
		}

		$data = self::getURLData($url);
		$search_data = json_decode($data);

		$lat = "";
		$lng = "";
		if (!empty($search_data)) {
			if ($mapType == MAP_TYPE_GOOGLE && !empty($search_data->results)) {
				$lat = $search_data->results[0]->geometry->location->lat;
				$lng = $search_data->results[0]->geometry->location->lng;

				if (!empty($limitCountries)) {
					foreach ($search_data->results as $result) {
						$country = "";
						foreach ($result->address_components as $addressCmp) {
							if (!empty($addressCmp->types) && $addressCmp->types[0] == "country") {
								$country = $addressCmp->short_name;
							}
						}
						if (in_array($country, $limitCountries)) {
							$lat = $result->geometry->location->lat;
							$lng = $result->geometry->location->lng;
						}
					}
				}
			} elseif ($mapType == MAP_TYPE_OSM) {
				$lat = $search_data[0]->lat;
				$lng = $search_data[0]->lon;

				if (!empty($limitCountries)) {
					$country = "";
					if (!empty($search_data[0]->address->country)) {
						$country = strtoupper($search_data[0]->address->country_code);
					}

					if (in_array($country, $limitCountries)) {
						$lat = $search_data[0]->lat;
						$lng = $search_data[0]->lon;
					}
				}
			}
		
			$location =  array();
			$location["latitude"] = $lat;
			$location["longitude"] = $lng;
		}
		
		return $location;
	}

	/**
	 * Calculate the difference between a date in the future (by number of days) and current date
	 *
	 * @param $days
	 * @return stdClass
	 */
	public static function parseDays($days) {
		$date1 = time();
		$date2 = strtotime("+$days day");

		$diff = abs($date2 - $date1);

		$years = floor($diff / (365*60*60*24));
		$months = floor(($diff - $years * 365*60*60*24) / (30*60*60*24));
		$days = floor(($diff - $years * 365*60*60*24 - $months*30*60*60*24)/ (60*60*24));
			
		$result = new stdClass();

		$result->days = $days;
		$result->months = $months;
		$result->years = $years;

		return $result;
	}

	/**
	 * get component name
	 *
	 * @return mixed component name
	 * @throws Exception
	 */
	public static function getComponentName() {
		return "com_jbusinessdirectory";
	}

	/**
	 * make path file
	 * @param $path string path
	 * @return string|string[]
	 */
	public static function makePathFile($path) {
		$path_tmp = str_replace('\\', DIRECTORY_SEPARATOR, $path);
		$path_tmp = str_replace('/', DIRECTORY_SEPARATOR, $path_tmp);
		return $path_tmp;
	}

	/**
	 * Get the current time based on the time zone
	 *
	 * @param [type] $time_zone
	 * @return void
	 */
	public static function getCurrentTime($time_zone){
		$currentTime="";

		$time_zone=intval($time_zone);
		$offset= $time_zone * 60 * 60;
		$currentTime = gmdate("H:i:s", time()+$offset);

		return $currentTime;
	}
	
	/**
	 * Convert time to Mysql Time Format
	 *
	 * @param $time string time
	 * @return false|string
	 */
	public static function convertTimeToMysqlFormat($time) {
		if (empty($time)) {
			return "00:00:00";
		}
		
		if ($time == '12:00 AM') {
			return '24:00:00';
		}
		
		$strtotime = strtotime($time);
		$time = date('H:i:s', $strtotime);
		
		return $time;
	}

	/**
	 * Convert time to application settings format
	 *
	 * @param $time string time
	 * @return false|string|null time converted or null if no time is provided
	 */
	public static function convertTimeToFormat($time) {
		if (empty($time)) {
			return null;
		}
		$appSettings = JBusinessUtil::getApplicationSettings();
		$strtotime = strtotime($time);
		$time = date($appSettings->time_format, $strtotime);
		return $time;
	}

	/**
	 * Convert date to application settings format
	 *
	 * @param $date string date
	 * @return false|string|null date converted or null if no date is provided
	 */
	public static function convertToFormat($date) {
		if (isset($date) && strlen($date)>6 && $date!="0000-00-00" && $date!="00-00-0000") {
			try {
				$appSettings = JBusinessUtil::getApplicationSettings();
				$date = substr($date, 0, 10);
				list($yy, $mm, $dd)=explode("-", $date);
				if (is_numeric($yy) && is_numeric($mm) && is_numeric($dd)) {
					$date = date($appSettings->dateFormat, strtotime($date));
				} else {
					$date=null;
				}
			} catch (Exception $e) {
				$date="";
			}
		}
		return $date;
	}

	/**
	 * Convert date to mysql date format
	 *
	 * @param $date string date
	 * @return false|string|null date converted or null if it is empty
	 */
	public static function convertToMysqlFormat($date) {
		if (strpos($date, "00-00-00")!==false) {
			return $date;
		} elseif (!empty($date) && strlen($date)>6) {
			$date = date("Y-m-d", strtotime($date));
		} else {
			$date = null;
		}
		return $date;
	}

	/**
	 * Covert a date to a general format
	 *
	 * @param $data string date
	 * @return string
	 */
	public static function getDateGeneralFormat($data) {
		$dateS="";
		if (isset($data) && strlen($data)>6  && $data!="0000-00-00") {
			//$data =strtotime($data);
			//setlocale(LC_ALL, 'de_DE');
			//$dateS = strftime( '%e %B %Y', $data );
			$date = JFactory::getDate($data);
			$dateS = $date->format('j F Y');
			//$dateS = date( 'j F Y', $data );
		}
	
		return $dateS;
	}

	/**
	 * Get date in ISO format
	 *
	 * @param $data string date
	 * @return string date
	 */
	public static function getDateISOFormat($data, $time = "") {
		$dateS="";
		if (isset($data) && strlen($data)>6  && $data!="0000-00-00") {
			//$data =strtotime($data);
			//setlocale(LC_ALL, 'de_DE');
			//$dateS = strftime( '%e %B %Y', $data );

			if(!empty($time)){
				$date = JFactory::getDate($data." ".$time);
				$dateS = $date->format('Y-m-dTH:m:s');
			}else{
				$date = JFactory::getDate($data);
				$dateS = $date->format('Y-m-d');
			}
		}
		
		return $dateS;
	}

	/**
	 * Convert a general date to a short format
	 *
	 * @param $data string date
	 * @return string
	 */
	public static function getDateGeneralShortFormat($data) {
		$dateS="";
		if (isset($data) && strlen($data)>6  && $data!="0000-00-00") {
			//$data =strtotime($data);
			//$dateS = strftime( '%e %b %Y', $data );
			//$dateS = date( 'j M Y', $data );
			$date = JFactory::getDate($data);
			$dateS = $date->format('j M Y');
		}
	
		return $dateS;
	}

	/**
	 * Get date gemeral format with time
	 *
	 * @param $data string date
	 * @return string|null
	 */
	public static function getDateGeneralFormatWithTime($data) {
		if (empty($data)) {
			return null;
		}
		$date = JFactory::getDate($data);
		$dateS =  $date->format('j M Y | G:i:s');
	
		return $dateS;
	}


	/**
	 * Get short date if format 'M j'
	 *
	 * @param $data string date
	 * @return string|null
	 */
	public static function getShortDate($data) {
		if (empty($data)) {
			return null;
		}
		
		$date = JFactory::getDate($data);
		$dateS = $date->format('M j');
	
		return $dateS;
	}

	/**
	 * Get short week date
	 *
	 * @param $data string data
	 * @return string|null
	 */
	public static function getShortWeekDate($data) {
		if (empty($data)) {
			return null;
		}
		
		$date = JFactory::getDate($data);
		$dateS = $date->format('D, M j');
		
		return $dateS;
	}

	/**
	 * Covert time in g:iA format
	 *
	 * @param $time string time
	 * @return false|string
	 */
	public static function getTimeText($time) {
		$result = date('g:i A', strtotime($time));
		
		return $result;
	}

	/**
	 * Get the remaining time up to a specific date
	 *
	 * @param $date string date
	 * @return string return time
	 * @throws Exception
	 */
	public static function getRemainingTime($date) {
		$now = new DateTime();
		$future_date = new DateTime($date);
		$timestamp = strtotime($date);
		$timestamp = strtotime('+1 day', $timestamp);
		if ($timestamp  < time()) {
			return "";
		}
		
		$interval = $future_date->diff($now);
		$result = JText::_("LNG_ENDS_IN");
		
		if($interval->format("%a")){
			$result .= " ".$interval->format("%a")." ".($interval->format("%a") == 1 ?strtolower(JText::_("LNG_DAY")): strtolower(JText::_("LNG_DAYS")));
		}
		if($interval->format("%h")){
			$result .= " ".$interval->format("%h")." ".($interval->format("%h") == 1 ?strtolower(JText::_("LNG_HOUR")): strtolower(JText::_("LNG_HOURS")));
		}
		if($interval->format("%i")){
			$result .= " ".$interval->format("%i")." ".($interval->format("%i") == 1 ?strtolower(JText::_("LNG_MIN")): strtolower(JText::_("LNG_MIN")));
		}
		
		
		return $result;
	}

	/**
	 * Substract time
	 * 
	 */
	public static function substractTime($time, $interval){
		$a = new DateTime($time);
		$b = new DateTime("00:$interval");
		$interval = $a->diff($b);
		
		$result = $interval->format("%H:%i");
		return $result;
	}

	/**
	 * Add time
	 * 
	 */
	public static function addTime($time, $interval){
		$a = new DateTime($time);
		$interval = "PT".$interval."M";
		$b = new DateInterval($interval);
		$interval = $a->add($b);

		$result = $interval->format("H:i");
		return $result;
	}

	/**
	 * Load modules that are available on a specific position
	 *
	 * @param $position string position
	 */
	public static function loadModules($position) {
		require_once(JPATH_ROOT.DS.'libraries'.DS.'joomla'.DS.'application'.DS.'module'.DS.'helper.php');
		$document = JFactory::getDocument();
		$renderer = $document->loadRenderer('module');
		$db =JFactory::getDBO();
		$db->setQuery("SELECT * FROM #__modules WHERE position='$position' AND published=1 ORDER BY ordering");
		$modules = $db->loadObjectList();
		if (count($modules) > 0) {
			foreach ($modules as $module) {
				//just to get rid of that stupid php warning
				$module->user = '';
				$params = array('style'=>'xhtml');
				echo $renderer->render($module, $params);
			}
		}
	}
	
	/**
	 * Get company details
	 * @param int $companyId company id
	 */
	public static function getCompany($companyId) {
		if (empty($companyId)) {
			return null;
		}
		
		JTable::addIncludePath(JPATH_ROOT.'/administrator/components/com_jbusinessdirectory/tables');
		$companiesTable = JTable::getInstance("Company", "JTable");
		$company = $companiesTable->getCompany($companyId);
		
		return $company;
	}

		/**
	 * Get company details
	 * @param int $companyId company id
	 */
	public static function updateCompanyUser($companyId, $userId) {
		if (empty($companyId)) {
			return null;
		}
		
		JTable::addIncludePath(JPATH_ROOT.'/administrator/components/com_jbusinessdirectory/tables');
		$companiesTable = JTable::getInstance("Company", "JTable");
		$companiesTable->load($companyId);
		$companiesTable->userId = $userId;

		if($companiesTable->store()){
			return true;
		}
		
		return false;
	}

	
	/**
	 * Get event details
	 * @param int $eventId
	 */
	public static function getEvent($eventId) {
		if (empty($eventId)) {
			return null;
		}
	
		JTable::addIncludePath(JPATH_ROOT.'/administrator/components/com_jbusinessdirectory/tables');
		$eventTable = JTable::getInstance("Event", "JTable");
		$event = $eventTable->getEvent($eventId);
	
		return $event;
	}
	
	/**
	 * Get offer details
	 * @param int $offerId
	 */
	public static function getOffer($offerId) {
		if (empty($offerId)) {
			return null;
		}
	
		JTable::addIncludePath(JPATH_ROOT.'/administrator/components/com_jbusinessdirectory/tables');
		$offerTable = JTable::getInstance("Offer", "JTable");
		$offer = $offerTable->getOffer($offerId);
	
		return $offer;
	}

	/**
	 * Get conference details
	 * @param int $conferenceId
	 */
	public static function getConference($conferenceId) {
		if (empty($conferenceId)) {
			return null;
		}
	
		JTable::addIncludePath(JPATH_ROOT.'/administrator/components/com_jbusinessdirectory/tables');
		$conferenceTable = JTable::getInstance("Conference", "JTable");
		$conference = $conferenceTable->getConference($conferenceId);
	
		return $conference;
	}

	/**
	 * Get speaker details
	 * @param int $speakerId
	 */
	public static function getSpeaker($speakerId) {
		if (empty($speakerId)) {
			return null;
		}
	
		JTable::addIncludePath(JPATH_ROOT.'/administrator/components/com_jbusinessdirectory/tables');
		$speakerTable = JTable::getInstance("Speaker", "JTable");
		$speaker = $speakerTable->getSpeaker($speakerId);
	
		return $speaker;
	}

	/**
	 * Get video details
	 * @param int $videoId
	 */
	public static function getVideo($videoId) {
		if (empty($videoId)) {
			return null;
		}
	
		JTable::addIncludePath(JPATH_ROOT.'/administrator/components/com_jbusinessdirectory/tables');
		$videoTable = JTable::getInstance("Videos", "Table");
		$video = $videoTable->getVideo($videoId);
	
		return $video;
	}
	
	/**
	 * Get session location details
	 * @param int $sessionLocationId
	 */
	public static function getSessionLocation($sessionLocationId) {
		if (empty($sessionLocationId)) {
			return null;
		}
	
		JTable::addIncludePath(JPATH_ROOT.'/administrator/components/com_jbusinessdirectory/tables');
		$sessionLocationTable = JTable::getInstance("Sessionlocation", "JTable");
		$sessionLocation = $sessionLocationTable->getSessionLocation($sessionLocationId);
	
		return $sessionLocation;
	}

	/**
	 * Get session name
	 * @param int $sessionId
	 */
	public static function getSessionName($sessionId) {
		if (empty($sessionId)) {
			return null;
		}
	
		JTable::addIncludePath(JPATH_ROOT.'/administrator/components/com_jbusinessdirectory/tables');
		$sessionTable = JTable::getInstance("Sessions", "JTable");
		$session = $sessionTable->getSessionName($sessionId);
	
		return $session;
	}

	/**
	 * Get article title
	 * @param int $articleId
	 */
	public static function getArticleTitle($articleId) {
		if (empty($articleId)) {
			return null;
		}
	
		JTable::addIncludePath(JPATH_ROOT.'/administrator/components/com_jbusinessdirectory/tables');
		$articleTable = JTable::getInstance("CompanyArticles", "Table");
		$article = $articleTable->getArticleTitle($articleId);
	
		return $article;
	}

	/**
	 * Get package by id
	 *
	 * @param $packageId int package id
	 * @return |null
	 */
	public static function getPackage($packageId) {
		if (empty($packageId)) {
			return null;
		}
		
		$packageTable = JTable::getInstance("Package", "JTable");
		$package = $packageTable->getPackage($packageId);
		
		$package->features = explode(",", $package->featuresS);
		$package->features[]= "multiple_categories";
		
		if (self::getInstance()->getApplicationSettings()->enable_multilingual) {
			JBusinessDirectoryTranslations::updateEntityTranslation($package, PACKAGE_TRANSLATION);
		}
		
		return $package;
	}

	/**
	 * Get current packages
	 * @return array
	 */
	public static function getPackages($showAdmin = true, $showAll = false) {
		JTable::addIncludePath(JPATH_ROOT.'/administrator/components/com_jbusinessdirectory/tables');
		$packageTable = JTable::getInstance("Package", "JTable");
		$packages = $packageTable->getPackages($showAdmin, $showAll);
		
		$result = array();
		foreach ($packages as $package) {
			$result[$package->id] = $package;
		}
		
		return $result;
	}
	
	/**
	 * Get custom attributes and filter them based on package features
	 * @return array
	 */
	public static function getPackagesAttributes($packages) {
		$attributesTable = JTable::getInstance('Attribute', 'JTable');
		$attributes = $attributesTable->getActiveAttributes();
	
		if (!is_array($packages)) {
			$packages = array($packages);
		}
		
		$result = array();
		//check if the attribues are contained in at least one package. If not it will be removed.
		foreach ($attributes as $attribute) {
			$found = false;
			foreach ($packages as $package) {
				foreach ($package->features as $feature) {
					if ($feature == $attribute->code) {
						$found = true;
					}
				}
			}
				
			if ($found) {
				$result[] = $attribute;
			}
		}
	
		if (self::getInstance()->getApplicationSettings()->enable_multilingual) {
			JBusinessDirectoryTranslations::updateAttributesTranslation($result);
		}
	
		return $result;
	}


	/**
	 * Get the package type unit in php time format
	 */
	public static function getTimeUnit($unit){

		if($unit=="Y"){
			return "years";
		}

		if($unit=="M"){
			return "months";
		}

		if($unit=="W"){
			return "weeks";
		}

		if($unit=="D"){
			return "days";
		}

		return "";
	}

	public static function getTrialText($package, $showPrice = true){
		$text= "";
		if($package->expiration_type == 4){

			if($showPrice){
				if($package->trial_price == 0){
					$text .= JText::_("LNG_FREE")." ".JText::_("LNG_FOR")." ";
				}else{
					$text = JBusinessUtil::getPriceFormat($package->trial_price);
					$text .= " ".JText::_("LNG_FOR")." ";
				}
			}else{
				$text = JText::_("LNG_TRY");
				$text .= " ".JText::_("LNG_FOR")." ";
			}
			
			$timePeriod = "";
			switch ($package->trial_period_unit) {
				case "D":
					$timePeriod = $package->trial_period_amount . " " . JText::_('LNG_DAYS');
					break;
				case "W":
					$timePeriod = $package->trial_period_amount . " " . JText::_('LNG_WEEKS');
					break;
				case "M":
					$timePeriod = $package->trial_period_amount . " " . JText::_('LNG_MONTHS');
					break;
				case "Y":
					$timePeriod = $package->trial_period_amount . " " . JText::_('LNG_YEARS');
					break;
				default:
				$timePeriod = $package->trial_period_amount;
			}

			$text .= $timePeriod;

		}

		return $text;
	}

	/**
	 * Get the package duratino as String
	 */
	public static function getTrialPackageDuration($package){

		$result = $package->trial_period_amount . " ";
		$time_unit = JText::_('LNG_DAYS');
		switch($package->trial_period_unit){
			case "D":
				$time_unit = $package->trial_period_amount>1?JText::_('LNG_DAYS'):JText::_('LNG_DAY');
				break;
			case "W":
				$time_unit = $package->trial_period_amount>1?JText::_('LNG_WEEKS'):JText::_('LNG_WEEK');
				break;
			case "M":
				$time_unit = $package->trial_period_amount>1?JText::_('LNG_MONTHS'):JText::_('LNG_MONTH');
				break;
			case "Y":
				$time_unit = $package->trial_period_amount>1?JText::_('LNG_YEARS'):JText::_('LNG_YEAR');
				break;
		}
		$result .= $time_unit;

		return $result;
	}

	/**
	 * Get the package duratino as String
	 */
	public static function getPackageDuration($package){

		$result = "";
		if($package->expiration_type == 1 || empty($package->expiration_type)){
			$result = JText::_('LNG_LIFE_TIME');
		}else{
			$result = $package->time_amount . " ";
			$time_unit = JText::_('LNG_DAYS');
			switch($package->time_unit){
				case "D":
					$time_unit = $package->time_amount>1?JText::_('LNG_DAYS'):JText::_('LNG_DAY');
					break;
				case "W":
					$time_unit = $package->time_amount>1?JText::_('LNG_WEEKS'):JText::_('LNG_WEEK');
					break;
				case "M":
					$time_unit = $package->time_amount>1?JText::_('LNG_MONTHS'):JText::_('LNG_MONTH');
					break;
				case "Y":
					$time_unit = $package->time_amount>1?JText::_('LNG_YEARS'):JText::_('LNG_YEAR');
					break;
			}
			$result .= $time_unit;

		}

		return $result;
	}

	/**
	 * Update the order end date
	 *
	 */
	public static function updateOrderEndTime(){
		JTable::addIncludePath(JPATH_ROOT.'/administrator/components/com_jbusinessdirectory/tables');
		$packages = self::getPackages(false, true);
		$ordersTable = JTable::getInstance("Order");

		$start = 0;
		$limit = 200;
		while($orders = $ordersTable->getOrdersWithoutEndDate($start, $limit)){
			foreach($orders as $order){

				//get the order package
				if(!empty($packages[$order->package_id])){
					$package = $packages[$order->package_id];
					$timeUnit = self::getTimeUnit($package->time_unit);

					$order->end_date = date('Y-m-d', strtotime($order->start_date. " + $package->time_amount $timeUnit"));
				} else {
					$order->end_date = $order->start_date;
				}

				$ordersTable->bind($order);
				$ordersTable->store();
			}
			$start += $limit;
		}

		return true;
	}

	/**
	 * Process listing packages to establish the state and expiration date
	 *
	 * @param $items
	 * @return mixed
	 */
	public static function processPackages($items) {
		JTable::addIncludePath(JPATH_ROOT.'/administrator/components/com_jbusinessdirectory/tables');
		if (empty($items)) {
			return $items;
		}
			
		$packagesTable =  JTable::getInstance("Package");
		$freePackage = $packagesTable->getFreePackage();
		$packages = self::getPackages(true, true);
		$active = false;
		
		foreach ($items as $item) {
			$packageStatus = array();
			if (!empty($item->orders)) {
				$active = false;
				$orders = explode("#|", $item->orders);
				foreach ($orders as $i=>$orderS) {
					$orderS = explode("|", $orderS);
				  
					$order = new stdClass();
					$order->start_date = $orderS[0];
					$order->start_trial_date = $orderS[1];
					$order->state = $orderS[2];
					$order->package_id = $orderS[3];
					$order->id = $orderS[4];
					$order->company_id = $orderS[5];
					$order->end_date = $orderS[6];
					$order->amount = $orderS[7];
					$order->trial_amount = $orderS[8];

					if (empty($order->package_id) || !isset($packages[$order->package_id])) {
						continue;
					}
					
					$package = $packages[$order->package_id];
					self::preparePackageText($package);

					$packgeInfo = new stdClass();
					$packgeInfo->name = $package->name;
					$packgeInfo->package_id = $package->id;
					$packgeInfo->expiration_type =  $package->expiration_type;
					//check if package is still active - between the start and end date
					$packgeInfo->active = ($package->price==0 || $package->expiration_type==1 || (time() > strtotime($order->start_date) && (time() < strtotime($order->end_date)) && $order->start_date!='0000-00-00')) ;
					$packgeInfo->price = $package->price;
					$packgeInfo->renewal_price = $package->renewal_price;
					$packgeInfo->details_text = $package->details_text;
					$packgeInfo->trial_period_unit = $package->trial_period_unit;
					$packgeInfo->trial_period_amount = $package->trial_period_amount;
					
					if ($packgeInfo->active) {
						$active = true;
					}
					$packgeInfo->state = $order->state;
					$packgeInfo->expirationDate = JBusinessUtil::getDateGeneralShortFormat($order->end_date);
					$packgeInfo->start_date = $order->start_date;
					$packgeInfo->future = (time() < strtotime($order->start_date) && $order->start_date!='0000-00-00');
					$packgeInfo->order_id = $order->id;
					$packgeInfo->company_id = $order->company_id;
					$packgeInfo->amount = $order->amount;
					$packgeInfo->trial_price = $order->trial_amount;

					if (!$packgeInfo->active && (count($orders) == 1 || $i >= (count($orders) - 3)) || ($packgeInfo->active || $packgeInfo->future)) {
						$packageStatus[] = $packgeInfo;
					}
				}
			}

			if (!empty($item->package_id) && isset($packages[$item->package_id])) {
				$currentPackage = $packages[$item->package_id];
				if ($currentPackage->price == 0) {
					$packgeInfo = new stdClass();
					$packgeInfo->name = $currentPackage->name;
					$packgeInfo->expiration_type =  $currentPackage->expiration_type;
					$packgeInfo->active = true;
					$packgeInfo->state = 1;
					$packgeInfo->future = false;
					if(!empty($package)){
						$packgeInfo->package_id = $package->id;
					}
					$packgeInfo->price = $currentPackage->price;
					$packgeInfo->trial_period_unit = $currentPackage->trial_period_unit;
					$packgeInfo->trial_period_amount = $currentPackage->trial_period_amount;
					$packageStatus[] = $packgeInfo;
				}
			}

			if (!empty($freePackage)) {
				$active = true;
			}
				
			$item->packgeInfo= $packageStatus;
			$item->active = $active;
		}
		
		return $items;
	}


	public static function preparePackageText(&$package){
		$text = '';

		$text = JBusinessUtil::getPackageDuration($package);

		if ($package->expiration_type == 3 || $package->expiration_type == 4) {
			if (!empty($package->recurrence_count)) {
				$text .= " | x" . $package->recurrence_count . " " . JText::_("LNG_OCCURANCES");
			}

			if ($package->expiration_type == 4) {
				$text .= " | trial: ";
				switch ($package->trial_period_unit) {
					case "D":
						$text .= $package->trial_period_amount . " " . JText::_('LNG_DAYS');
						break;
					case "W":
						$text .= $package->trial_period_amount . " " . JText::_('LNG_WEEKS');
						break;
					case "M":
						$text .= $package->trial_period_amount . " " . JText::_('LNG_MONTHS');
						break;
					case "Y":
						$text .= $package->trial_period_amount . " " . JText::_('LNG_YEARS');
						break;
					default:
						$text .= $package->trial_period_amount;
				}

				if (!empty($package->trial_price)) {
					$text .= " " . JBusinessUtil::getPriceFormat($package->trial_price);
				}
			}
		}
		
		$package->details_text = $text;
		$package->price_text = JBusinessUtil::getPriceFormat($package->price);
	}

	/**
	 * Set the active menu item on sessions
	 *
	 * @throws Exception
	 */
	public static function setMenuItemId() {
		$session = JFactory::getSession();
		
		$lang = JFactory::getLanguage();
		$app = JFactory::getApplication();
		$menu = $app->getMenu();
		$activeMenu = $app->getMenu()->getActive();
		
		$url = $_SERVER['REQUEST_URI'];
		$urlParts = parse_url($url);
		$menuId="";
		
		if ((!empty($activeMenu) && $menu->getActive() != $menu->getDefault($lang->getTag()))
			|| ($urlParts["path"]=='/' && empty($urlParts["query"]))) {
			$menuId = $activeMenu->id;
			$session->set('menuId', $menuId);
		}
	}

	/**
	 * Build the menu item URL parameter based on the active menu item
	 *
	 * @return string
	 * @throws Exception
	 */
	public static function getItemIdS() {
		$app = JFactory::getApplication();
		$lang = JFactory::getLanguage();
		$menu = $app->getMenu();
		$itemid="";
		
		$activeMenu = JFactory::getApplication()->getMenu()->getActive();
		if (isset($activeMenu)) {
			$itemid= JFactory::getApplication()->getMenu()->getActive()->id;
		}
		
		$defaultMenu = $menu->getDefault($lang->getTag());
		if (!empty($defaultMenu) && $itemid == $defaultMenu->id) {
			$itemid	= "";
		}
		
		$appSettings = JBusinessUtil::getApplicationSettings();
		if (!empty($appSettings->menu_item_id) && empty($itemid)) {
			$itemid = $appSettings->menu_item_id;
		}
		
		$itemidS="";
		if (!empty($itemid)) {
			$itemidS = '&Itemid='.$itemid;
		}
		
		return $itemidS;
	}

	/**
	 * Get the current menu alias
	 *
	 * @return string
	 */
	public static function getCurrentMenuAlias() {
		$menualias =  "";
		
		$appSettings = JBusinessUtil::getApplicationSettings();
		
		return $appSettings->url_menu_alias;
		/*
		$currentMenu = null;
		if(!empty($appSettings->menu_item_id)){
			$currentMenu = JFactory::getApplication()->getMenu()->getItem($appSettings->menu_item_id);
		}

		if(empty($currentMenu)){
			$currentMenu = JFactory::getApplication()->getMenu()->getActive();
		}

		if(!empty($currentMenu))
			$menualias = $currentMenu->alias;*/
		
		return $menualias;
	}

	/**
	 * Prevent the links to contain administrator keyword
	 *
	 * @param $url string url path
	 * @return string|string[]
	 */
	public static function processURL($url) {
		if (strpos($url, "/administrator/")!==false) {
			$url = str_replace("administrator/", "", $url);
		}
		
		return $url;
	}

	/**
	 * Retrieve the status of the url language code based on language filter plugin
	 * 
	 */
	public static function getURLLanguageCodeStatus(){
		$languagePlugin = JPluginHelper::getPlugin('system', 'languagefilter');
		if (empty($languagePlugin)) {
			return false;
		} else {
			$params = new JRegistry($languagePlugin->params);
			$removePrefix = $params->get('remove_default_prefix');
			if(!$removePrefix){
				return true;
			}
		}
		
		return false;
	}

	/**
	 * Generate the business listing link
	 *
	 * @param $company object company
	 * @param null $addIndex
	 * @return string|string[]
	 * @throws Exception
	 */
	public static function getCompanyLink($company, $addIndex=null) {
		$itemidS = self::getItemIdS();
	
		$companyAlias = trim($company->alias);
		$companyAlias = stripslashes(strtolower($companyAlias));
		$companyAlias = str_replace(" ", "-", $companyAlias);
	
		$conf = JBusinessUtil::getSiteConfig();
		$index ="";
	
		if (!JBusinessUtil::getSiteConfig()->sef_rewrite) {
			$index ="index.php/";
		}
	
		$appSettings = JBusinessUtil::getApplicationSettings();

		if ($appSettings->open_business_website == "1" && !empty($company->website)) {
			return $company->website;
		} elseif (!$appSettings->enable_seo) {
			$companyLink = $company->id;
			if (JBusinessUtil::getSiteConfig()->sef) {
				$companyLink = $company->id;
			}
			$url = JRoute::_('index.php?option=com_jbusinessdirectory&view=companies&companyId='.$companyLink, false, -1);
		} else {
			if ($appSettings->add_url_id == 1) {
				$companyLink = $company->id."-".htmlentities(urlencode($companyAlias));
			} else {
				$companyLink = htmlentities(urlencode($companyAlias));
			}
			
			$urlParts = array();
			if (!empty($appSettings->url_fields)) {
				if (in_array("category", $appSettings->url_fields)) {
					$categoryPath = self::getBusinessCategoryPath($company);
					if (!empty($categoryPath)) {
						$path="";
						foreach ($categoryPath as $cp) {
							if ($appSettings->enable_multilingual) {
								if (!class_exists('JBusinessDirectoryTranslations')) {
									require_once HELPERS_PATH.'/translations.php';
								}
								
								JBusinessDirectoryTranslations::updateEntityTranslation($cp, CATEGORY_TRANSLATION);
							}
							$path = $path. JApplicationHelper::stringURLSafe($cp->name)."/";
						}
						$path = substr($path, 0, -1);
						array_push($urlParts, strtolower($path));
					}
				}
				if (in_array("province", $appSettings->url_fields) && !empty($company->province)) {
					array_push($urlParts, strtolower($company->province));
				}
				if (in_array("region", $appSettings->url_fields) && !empty($company->county)) {
					array_push($urlParts, strtolower($company->county));
				}
				if (in_array("city", $appSettings->url_fields) && !empty($company->city)) {
					array_push($urlParts, strtolower($company->city));
				}
				
				array_push($urlParts, $companyLink);
				$urlParts = array_filter($urlParts);
				$companyLink = implode("/", $urlParts);
			} else {
				//$company->county = JApplicationHelper::stringURLSafe($company->county);
				//$company->city = JApplicationHelper::stringURLSafe($company->city);
				//$company->province = JApplicationHelper::stringURLSafe($company->province);
				
				if ($appSettings->listing_url_type==2) {
					$categoryPath = self::getBusinessCategoryPath($company);
					$path="";
					foreach ($categoryPath as $cp) {
						$path = $path. JApplicationHelper::stringURLSafe($cp->name)."/";
					}
					$companyLink=strtolower($path).$companyLink;
				} elseif ($appSettings->listing_url_type==3) {
					$companyLink= strtolower($company->county)."/".strtolower($company->city)."/".$companyLink;
				} elseif ($appSettings->listing_url_type==4) {
					$categoryPath = self::getBusinessCategoryPath($company);
					$path="";
					foreach ($categoryPath as $cp) {
						$path = $path. JApplicationHelper::stringURLSafe($cp->name)."/";
					}
					$companyLink= $path.strtolower($company->province)."/".$companyLink;
				} elseif ($appSettings->listing_url_type==5) {
					$categoryPath = self::getBusinessCategoryPath($company);
					$path = "";
					if (!empty($categoryPath) && isset($categoryPath[0]->name)) {
						$path=JApplication::stringURLSafe($categoryPath[0]->name);
					}
					$companyLink= $path."/".strtolower($company->province)."/".$companyLink;
				} elseif ($appSettings->listing_url_type==6) {
					$categoryPath = self::getBusinessCategoryPath($company);
					$path=JApplication::stringURLSafe($categoryPath[0]->name);
					$countryName = "";
					if (isset($company->countryName)) {
						$countryName = $company->countryName;
					} elseif (isset($company->country_name)) {
						$countryName = $company->country_name;
					}
				   
					$countryName = JApplicationHelper::stringURLSafe($countryName);
					$companyLink= $path."/".strtolower($countryName)."/".$companyLink;
				}
			}

			$base = JBusinessUtil::getWebsiteURL(true).$index;
			$urlLngCodeStatus = self::getURLLanguageCodeStatus();
			if ($appSettings->add_url_language || $urlLngCodeStatus) {
				$langTag = self::getCurrentLanguageCode();
				$base.= $langTag."/";
			}
			
			$url = $base.$companyLink;
			
			$menuAlias = self::getCurrentMenuAlias();
			if ($appSettings->enable_menu_alias_url && !empty($menuAlias)) {
				$url = $base.$menuAlias."/".$companyLink;
			}
		}
		
		$url = self::processURL($url);
	
		return $url;
	}
	
	/**
	 * Generate the business listing link only for type one (only name in the link)
	 *
	 * @param $companyId int company Id
	 * @param $companyAlias string company alias
	 * @param $addIndex boolean add index or no
	 * @return String $url
	 */
	public static function getCompanyDefaultLink($companyId, $addIndex=null) {
		$company = self::getCompany($companyId);
		$url = self::getCompanyLink($company, $addIndex);
		
		return $url;
	}

	/**
	 * Generate the link for categories
	 *
	 * @param $categoryId int category Id
	 * @param $categoryAlias string category alias
	 * @param $addIndex boolean true or false to add index
	 * @return string|string[]
	 * @throws Exception
	 */
	public static function getCategoryLink($categoryId, $categoryAlias, $addIndex=null) {
		$itemidS = self::getItemIdS();
		
		$appSettings = JBusinessUtil::getApplicationSettings();
		
		$categoryAlias = trim($categoryAlias);
		$categoryAlias = stripslashes(strtolower($categoryAlias));
		$categoryAlias = str_replace(" ", "-", $categoryAlias);
	
		$conf = JBusinessUtil::getSiteConfig();
		$index ="";
		if (!JBusinessUtil::getSiteConfig()->sef_rewrite) {
			$index ="index.php/";
		}
	
		$categoryLink = $categoryId;
		
		if (!$appSettings->enable_seo) {
			$categoryLink = $categoryId;
			if (JBusinessUtil::getSiteConfig()->sef) {
				$categoryLink = $categoryId;
			}
			$url = JRoute::_('index.php?option=com_jbusinessdirectory&view=search&categoryId='.$categoryLink, false, -1);
		} else {
			if ($appSettings->add_url_id == 1) {
				$categoryLink = $categoryId."-".htmlentities(urlencode($categoryAlias));
			} else {
				$categoryLink = htmlentities(urlencode($categoryAlias));
			}

			$base = JBusinessUtil::getWebsiteURL(true).$index;
			$urlLngCodeStatus = self::getURLLanguageCodeStatus();
			if ($appSettings->add_url_language || $urlLngCodeStatus) {
				$langTag = self::getCurrentLanguageCode();
				$base.= $langTag."/";
			}
			
			$menuAlias = self::getCurrentMenuAlias();
			if ($appSettings->category_url_type==2) {
				$url = $base.$categoryLink;
				if ($appSettings->enable_menu_alias_url && !empty($menuAlias)) {
					$url = $base.$menuAlias."/".$categoryLink;
				}
			} else {
				$url = $base.$appSettings->category_url_naming."/".$categoryLink;
				if ($appSettings->enable_menu_alias_url && !empty($menuAlias)) {
					$url = $base.$menuAlias."/".$appSettings->category_url_naming."/".$categoryLink;
				}
			}
		}
		
		$url = self::processURL($url);
		
		return $url;
	}

	/**
	 *
	 * Generate the offer category link
	 *
	 * @param $categoryId int get categpry link
	 * @param $categoryAlias string category alias
	 * @param $addIndex boolean true or false to add index
	 * @return string|string[]
	 * @throws Exception
	 */
	public static function getOfferCategoryLink($categoryId, $categoryAlias, $addIndex=null) {
		$itemidS = self::getItemIdS();
		
		$appSettings = JBusinessUtil::getApplicationSettings();
	
		$categoryAlias = trim($categoryAlias);
		$categoryAlias = stripslashes(strtolower($categoryAlias));
		$categoryAlias = str_replace(" ", "-", $categoryAlias);
	
		$conf = JBusinessUtil::getSiteConfig();
		$index ="";
		if (!JBusinessUtil::getSiteConfig()->sef_rewrite) {
			$index ="index.php/";
		}
	
		$offerCategoryLink = $categoryId;
		
		if (!$appSettings->enable_seo) {
			$offerCategoryLink = $categoryId;
			if (JBusinessUtil::getSiteConfig()->sef) {
				$categoryLink = $categoryId;
			}
			$url = JRoute::_('index.php?option=com_jbusinessdirectory&view=offers&offerCategoryId='.$offerCategoryLink, false, -1);
		} else {
			if ($appSettings->add_url_id == 1) {
				$offerCategoryLink = $categoryId."-".htmlentities(urlencode($categoryAlias));
			} else {
				$offerCategoryLink =htmlentities(urlencode($categoryAlias));
			}
			
			$base = JBusinessUtil::getWebsiteURL(true).$index;
			$urlLngCodeStatus = self::getURLLanguageCodeStatus();
			if ($appSettings->add_url_language || $urlLngCodeStatus) {
				$langTag = self::getCurrentLanguageCode();
				$base.= $langTag."/";
			}
			
			$url = $base.$appSettings->offer_category_url_naming."/".$offerCategoryLink;
			
			$menuAlias = self::getCurrentMenuAlias();
			if ($appSettings->enable_menu_alias_url && !empty($menuAlias)) {
				$url = $base.$menuAlias."/".$appSettings->offer_category_url_naming."/".$offerCategoryLink;
			}
		}
		
		$url = self::processURL($url);
		
		return $url;
	}
	
	/**
	 * Generate the link for event categories
	 *
	 * @param $categoryId int category id
	 * @param $categoryAlias string category alias
	 * @param $addIndex boolean true or false to add index or not
	 */
	public static function getEventCategoryLink($categoryId, $categoryAlias, $addIndex=null) {
		$app = JFactory::getApplication();
		$lang = JFactory::getLanguage();
		$menu = $app->getMenu();
		$itemid="";
		$activeMenu = JFactory::getApplication()->getMenu()->getActive();
		if (isset($activeMenu)) {
			$itemid= JFactory::getApplication()->getMenu()->getActive()->id;
		}
		
		if ($itemid == $menu->getDefault($lang->getTag())->id) {
			$itemid	= "";
		}
		
		$appSettings = JBusinessUtil::getApplicationSettings();
	
		$categoryAlias = trim($categoryAlias);
		$categoryAlias = stripslashes(strtolower($categoryAlias));
		$categoryAlias = str_replace(" ", "-", $categoryAlias);
	
		$conf = JBusinessUtil::getSiteConfig();
		$index ="";
		if (!JBusinessUtil::getSiteConfig()->sef_rewrite) {
			$index ="index.php/";
		}
	
		if (!$appSettings->enable_seo) {
			$eventCategoryLink = $categoryId;
			if (JBusinessUtil::getSiteConfig()->sef) {
				$categoryLink = $categoryId;
			}
			$url = JRoute::_('index.php?option=com_jbusinessdirectory&view=events&eventCategoryId='.$eventCategoryLink, false, -1);
		} else {
			if ($appSettings->add_url_id == 1) {
				$eventCategoryLink = $categoryId."-".htmlentities(urlencode($categoryAlias));
			} else {
				$eventCategoryLink = htmlentities(urlencode($categoryAlias));
			}

			$base = JBusinessUtil::getWebsiteURL(true).$index;
			$urlLngCodeStatus = self::getURLLanguageCodeStatus();
			if ($appSettings->add_url_language || $urlLngCodeStatus) {
				$langTag = self::getCurrentLanguageCode();
				$base.= $langTag."/";
			}
			
			$url = $base.$appSettings->event_category_url_naming."/".$eventCategoryLink;
			
			$menuAlias = self::getCurrentMenuAlias();
			if ($appSettings->enable_menu_alias_url && !empty($menuAlias)) {
				$url = $base.$menuAlias."/".$appSettings->event_category_url_naming."/".$eventCategoryLink;
			}
		}
	
		$url = self::processURL($url);
		
		return $url;
	}

	/**
	 * Generate the link for categories
	 *
	 * @param $categoryId int category Id
	 * @param $categoryAlias string category alias
	 * @param $addIndex boolean true or false to add index
	 * @return string|string[]
	 * @throws Exception
	 */
	public static function getCategoryCityLink($categoryId, $categoryAlias, $city) {
		$itemidS = self::getItemIdS();
		
		$appSettings = JBusinessUtil::getApplicationSettings();
		
		$categoryAlias = trim($categoryAlias);
		$categoryAlias = stripslashes(strtolower($categoryAlias));
		$categoryAlias = str_replace(" ", "-", $categoryAlias);
	
		$city = trim($city);
		$city = stripslashes(strtolower($city));
		$city = str_replace(" ", "-", $city);

		$conf = JBusinessUtil::getSiteConfig();
		$index ="";
		if (!JBusinessUtil::getSiteConfig()->sef_rewrite) {
			$index ="index.php/";
		}
	
		$categoryLink = $categoryId;
		
		if (!$appSettings->enable_seo) {
			$categoryLink = $categoryId;
			if (JBusinessUtil::getSiteConfig()->sef) {
				$categoryLink = $categoryId;
			}
			$url = JRoute::_('index.php?option=com_jbusinessdirectory&view=search&categoryId='.$categoryLink."&citySearch=".$city, false, -1);
		} else {
			if ($appSettings->add_url_id == 1) {
				$categoryLink = $categoryId."-".htmlentities(urlencode($categoryAlias));
			} else {
				$categoryLink = htmlentities(urlencode($categoryAlias));
			}

			$categoryLink .= "/".$city;

			$base = JBusinessUtil::getWebsiteURL(true).$index;
			$urlLngCodeStatus = self::getURLLanguageCodeStatus();
			if ($appSettings->add_url_language || $urlLngCodeStatus) {
				$langTag = self::getCurrentLanguageCode();
				$base.= $langTag."/";
			}
			
			$menuAlias = self::getCurrentMenuAlias();
			if ($appSettings->category_url_type==2) {
				$url = $base.$categoryLink;
				if ($appSettings->enable_menu_alias_url && !empty($menuAlias)) {
					$url = $base.$menuAlias."/".$categoryLink;
				}
			} else {
				$url = $base.$categoryLink;
				if ($appSettings->enable_menu_alias_url && !empty($menuAlias)) {
					$url = $base.$menuAlias."/".$categoryLink;
				}
			}
		}
		
		$url = self::processURL($url);
		
		return $url;
	}

	/**
	 * Get the search url based on country, region, city, category
	 */
	public static function getSearchURL($countryId, $region=null, $city=null, $categoryId=null) {

		$url = JRoute::_("index.php?option=com_jbusinessdirectory&view=search&categoryId=$categoryId&citySearch=$city&regionSearch=$region&countrySearch=$countryId", false, -1);

		return $url;
	}

	
	/**
	 * Generate the link for city
	 *
	 * @param $categoryId int category Id
	 * @param $categoryAlias string category alias
	 * @param $addIndex boolean true or false to add index
	 * @return string|string[]
	 * @throws Exception
	 */
	public static function getCityLink($city, $addPrefix = false) {
		$itemidS = self::getItemIdS();
		
		$appSettings = JBusinessUtil::getApplicationSettings();
		
		$city = trim($city);
		$city = stripslashes(strtolower($city));
		$city = str_replace(" ", "-", $city);
	
		$conf = JBusinessUtil::getSiteConfig();
		$index ="";
		if (!JBusinessUtil::getSiteConfig()->sef_rewrite) {
			$index ="index.php/";
		}
	
		$cityLink = $city;
		$url = "";
		if (!$appSettings->enable_seo) {
			$cityLink = $city;
			if (JBusinessUtil::getSiteConfig()->sef) {
				$cityLink = $city;
			}
			$url = JRoute::_('index.php?option=com_jbusinessdirectory&view=search&citySearch='.$cityLink, false, -1);
		} else {
			$cityLink = htmlentities(urlencode($city));			

			$base = JBusinessUtil::getWebsiteURL(true).$index;
			$urlLngCodeStatus = self::getURLLanguageCodeStatus();
			if ($appSettings->add_url_language || $urlLngCodeStatus) {
				$langTag = self::getCurrentLanguageCode();
				$base.= $langTag."/";
			}
			
			$menuAlias = self::getCurrentMenuAlias();
			
			if($addPrefix){
				$cityLink = $appSettings->city_url_naming."/".$cityLink;
			}

			$url = $base.$cityLink;
			if ($appSettings->enable_menu_alias_url && !empty($menuAlias)) {
				$url = $base.$menuAlias."/".$cityLink;
			}
			
		}
		
		$url = self::processURL($url);
		
		return $url;
	}

	/**
	 * Generate the link for an offer
	 *
	 * @param $offerId int offer id
	 * @param $offerAlias string offer alias
	 * @param $addIndex boolean true or false to add index or not
	 */
	public static function getOfferLink($offerId, $offerAlias, $addIndex=null) {
		$itemidS = self::getItemIdS();
		
		$appSettings = JBusinessUtil::getApplicationSettings();
	
		$offerAlias = trim($offerAlias);
		$offerAlias = stripslashes(strtolower($offerAlias));
		$offerAlias = str_replace(" ", "-", $offerAlias);
	
		$conf = JBusinessUtil::getSiteConfig();
		$index ="";
		if (!JBusinessUtil::getSiteConfig()->sef_rewrite) {
			$index ="index.php/";
		}
	
		$offerLink = $offerId;
		
		if (!$appSettings->enable_seo) {
			$offerLink = $offerId;
			if (JBusinessUtil::getSiteConfig()->sef) {
				$offerLink = $offerId;
			}
			$url = JRoute::_('index.php?option=com_jbusinessdirectory&view=offer&offerId='.$offerLink, false, -1);
		} else {
			if ($appSettings->add_url_id == 1) {
				$offerLink = $offerId."-".htmlentities(urlencode($offerAlias));
			} else {
				$offerLink = htmlentities(urlencode($offerAlias));
			}
			
			$base = JBusinessUtil::getWebsiteURL(true).$index;
			$urlLngCodeStatus = self::getURLLanguageCodeStatus();
			if ($appSettings->add_url_language || $urlLngCodeStatus) {
				$langTag = self::getCurrentLanguageCode();
				$base.= $langTag."/";
			}
			$url = $base.$appSettings->offer_url_naming."/".$offerLink;
			
			$menuAlias = self::getCurrentMenuAlias();
			if ($appSettings->enable_menu_alias_url && !empty($menuAlias)) {
				$url = $base.$menuAlias."/".$appSettings->offer_url_naming."/".$offerLink;
			}
		}
		
		$url = self::processURL($url);
		
		return $url;
	}
	
	/**
	 * Generate the link for an event
	 *
	 * @param $eventId int event id
	 * @param $eventAlias string event alias
	 * @param $addIndex true or false add index
	 */
	public static function getEventLink($eventId, $eventAlias, $addIndex=null) {
		$itemidS = self::getItemIdS();
		
		$appSettings = JBusinessUtil::getApplicationSettings();
		
		$eventAlias = trim($eventAlias);
		$eventAlias = stripslashes(strtolower($eventAlias));
		$eventAlias = str_replace(" ", "-", $eventAlias);
	
		$conf = JBusinessUtil::getSiteConfig();
		$index ="";
		if (!JBusinessUtil::getSiteConfig()->sef_rewrite) {
			$index ="index.php/";
		}
	
		if (!$appSettings->enable_seo) {
			$eventLink = $eventId;
			if (JBusinessUtil::getSiteConfig()->sef) {
				$categoryLink = $eventId;
			}
			$url = JRoute::_('index.php?option=com_jbusinessdirectory&view=event&eventId='.$eventLink, false, -1);
		} else {
			if ($appSettings->add_url_id == 1) {
				$eventLink = $eventId."-".htmlentities(urlencode($eventAlias));
			} else {
				$eventLink = htmlentities(urlencode($eventAlias));
			}
			
			$base = JBusinessUtil::getWebsiteURL(true).$index;
			$urlLngCodeStatus = self::getURLLanguageCodeStatus();
			if ($appSettings->add_url_language || $urlLngCodeStatus) {
				$langTag = self::getCurrentLanguageCode();
				$base.= $langTag."/";
			}
			
			$url = $base.$appSettings->event_url_naming."/".$eventLink;
			
			$menuAlias = self::getCurrentMenuAlias();
			if ($appSettings->enable_menu_alias_url && !empty($menuAlias)) {
				$url = $base.$menuAlias."/".$appSettings->event_url_naming."/".$eventLink;
			}
		}
		
		$url = self::processURL($url);
	
		return $url;
	}
	
	/**
	 * Generate the link for a conference
	 *
	 * @param $conferenceId int conference id
	 * @param $conferenceAlias string conference alias
	 * @param $addIndex true or false add index
	 */
	public static function getConferenceLink($conferenceId, $conferenceAlias, $addIndex=null) {
		$appSettings = JBusinessUtil::getApplicationSettings();
	
		$itemid = JFactory::getApplication()->input->getInt('Itemid');
	
		$conferenceAlias = trim($conferenceAlias);
		$conferenceAlias = stripslashes(strtolower($conferenceAlias));
		$conferenceAlias = str_replace(" ", "-", $conferenceAlias);
	
		$conf = JBusinessUtil::getSiteConfig();
		$index ="";
		if (!JBusinessUtil::getSiteConfig()->sef_rewrite) {
			$index ="index.php/";
		}
	
		if (!$appSettings->enable_seo) {
			$conferenceLink = $conferenceId;
			if (JBusinessUtil::getSiteConfig()->sef) {
				$conferenceLink = $conferenceId;
			}
			$url = JRoute::_('index.php?option=com_jbusinessdirectory&view=conference&conferenceId='.$conferenceId, false, -1);
		} else {
			if ($appSettings->add_url_id == 1) {
				$conferenceLink = $conferenceId."-".htmlentities(urlencode($conferenceAlias));
			} else {
				$conferenceLink = htmlentities(urlencode($conferenceAlias));
			}
			
			$base = JBusinessUtil::getWebsiteURL(true).$index;
			$urlLngCodeStatus = self::getURLLanguageCodeStatus();
			if ($appSettings->add_url_language || $urlLngCodeStatus) {
				$langTag = self::getCurrentLanguageCode();
				$base.= $langTag."/";
			}
			$url = $base.$appSettings->conference_url_naming."/".$conferenceLink;
			
			$menuAlias = self::getCurrentMenuAlias();
			if ($appSettings->enable_menu_alias_url && !empty($menuAlias)) {
				$url = $base.$menuAlias."/".$appSettings->conference_url_naming."/".$conferenceLink;
			}
		}
	
		return $url;
	}
	
	/**
	 * Generate the link for a conference session
	 *
	 * @param $sessionId int session Id
	 * @param $sessionAlias string session alias
	 * @param $addIndex boolean true or false to add the index
	 * @return string
	 */
	public static function getConferenceSessionLink($sessionId, $sessionAlias, $addIndex=null) {
		$appSettings = JBusinessUtil::getApplicationSettings();
	
		$itemid = JFactory::getApplication()->input->getInt('Itemid');
	
		$sessionAlias = trim($sessionAlias);
		$sessionAlias = stripslashes(strtolower($sessionAlias));
		$sessionAlias = str_replace(" ", "-", $sessionAlias);
	
		$conf = JBusinessUtil::getSiteConfig();
		$index ="";
		if (!JBusinessUtil::getSiteConfig()->sef_rewrite) {
			$index ="index.php/";
		}
	
		if (!$appSettings->enable_seo) {
			$sessionLink = $sessionId;
			if (JBusinessUtil::getSiteConfig()->sef) {
				$sessionLink = $sessionId;
			}
			$url = JRoute::_('index.php?option=com_jbusinessdirectory&view=conferencesession&cSessionId='.$sessionLink, false, -1);
		} else {
			if ($appSettings->add_url_id == 1) {
				$sessionLink = $sessionId."-".htmlentities(urlencode($sessionAlias));
			} else {
				$sessionLink = htmlentities(urlencode($sessionAlias));
			}
			
			$base = JBusinessUtil::getWebsiteURL(true).$index;
			$urlLngCodeStatus = self::getURLLanguageCodeStatus();
			if ($appSettings->add_url_language || $urlLngCodeStatus) {
				$langTag = self::getCurrentLanguageCode();
				$base.= $langTag."/";
			}
			
			$url = $base.$appSettings->conference_session_url_naming."/".$sessionLink;
			
			$menuAlias = self::getCurrentMenuAlias();
			if ($appSettings->enable_menu_alias_url && !empty($menuAlias)) {
				$url = $base.$menuAlias."/".$appSettings->conference_session_url_naming."/".$sessionLink;
			}
		}
	
		return $url;
	}

	/**
	 * Generate the link for a speaker
	 *
	 * @param $speakerId int speaker id
	 * @param $speakerAlias string speaker alias
	 * @param $addIndex boolean true or false to add the index
	 * @return string
	 * @throws Exception
	 */
	public static function getSpeakerLink($speakerId, $speakerAlias, $addIndex=null) {
		$appSettings = JBusinessUtil::getApplicationSettings();
	
		$itemid = JFactory::getApplication()->input->getInt('Itemid');
	
		$speakerAlias = trim($speakerAlias);
		$speakerAlias = stripslashes(strtolower($speakerAlias));
		$speakerAlias = str_replace(" ", "-", $speakerAlias);
	
		$conf = JBusinessUtil::getSiteConfig();
		$index ="";
		if (!JBusinessUtil::getSiteConfig()->sef_rewrite) {
			$index ="index.php/";
		}
	
		if (!$appSettings->enable_seo) {
			$speakerLink = $speakerId;
			if (JBusinessUtil::getSiteConfig()->sef) {
				$speakerLink = $speakerId;
			}
			$url = JRoute::_('index.php?option=com_jbusinessdirectory&view=speaker&speakerId='.$speakerLink, false, -1);
		} else {
			if ($appSettings->add_url_id == 1) {
				$speakerLink = $speakerId."-".htmlentities(urlencode($speakerAlias));
			} else {
				$speakerLink = htmlentities(urlencode($speakerAlias));
			}
			
			$base = JBusinessUtil::getWebsiteURL(true).$index;
			$urlLngCodeStatus = self::getURLLanguageCodeStatus();
			if ($appSettings->add_url_language || $urlLngCodeStatus) {
				$langTag = self::getCurrentLanguageCode();
				$base.= $langTag."/";
			}
			$url = $base.$appSettings->speaker_url_naming."/".$speakerLink;
			
			$menuAlias = self::getCurrentMenuAlias();
			if ($appSettings->enable_menu_alias_url && !empty($menuAlias)) {
				$url = $base.$menuAlias."/".$appSettings->speaker_url_naming."/".$speakerLink;
			}
		}
	
		return $url;
	}


	/**
	 * Generate the link for a video
	 *
	 * @param $videoId int video id
	 * @param $videoAlias string video alias
	 * @param $addIndex boolean true or false to add the index
	 * @return string
	 * @throws Exception
	 */
	public static function getVideoLink($video, $addIndex=null) {
		$appSettings = JBusinessUtil::getApplicationSettings();
		$appSettings->video_url_naming = "video";

		$itemid = JFactory::getApplication()->input->getInt('Itemid');

		$videoAlias = trim($video->alias);
		$videoAlias = stripslashes(strtolower($videoAlias));
		$videoAlias = str_replace(" ", "-", $videoAlias);

		$conf = JBusinessUtil::getSiteConfig();
		$index ="";
		if (!JBusinessUtil::getSiteConfig()->sef_rewrite) {
			$index ="index.php/";
		}

		$url = "";
		$videoLink="";
		if (!$appSettings->enable_seo) {
			$videoLink = $video->id;
			if (JBusinessUtil::getSiteConfig()->sef) {
				$videoLink = $video->id;
			}
			$url = JRoute::_('index.php?option=com_jbusinessdirectory&view=video&videoId='.$videoLink, false, -1);
		} else {

			$category = self::getCategoryItem($video->main_subcategory);
			if(!empty($category)){
				$videoLink =  $category->alias."/";
			}

			if ($appSettings->add_url_id == 1) {
				$videoLink .= $video->id."-".htmlentities(urlencode($videoAlias));
			} else {
				$videoLink .= htmlentities(urlencode($videoAlias));
			}

			$base = JBusinessUtil::getWebsiteURL(true).$index;
			$urlLngCodeStatus = self::getURLLanguageCodeStatus();
			if ($appSettings->add_url_language || $urlLngCodeStatus) {
				$langTag = self::getCurrentLanguageCode();
				$base.= $langTag."/";
			}
			$url = $base.$appSettings->video_url_naming."/".$videoLink;

			$menuAlias = self::getCurrentMenuAlias();
			if ($appSettings->enable_menu_alias_url && !empty($menuAlias)) {
				$url = $base.$menuAlias."/".$appSettings->video_url_naming."/".$videoLink;
			}
		}

		return $url;
	}

	/**
	 * Generate the link for a trip
	 *
	 * @param $tripId int conference id
	 * @param $tripAlias string conference alias
	 * @param $addIndex true or false add index
	 */
	public static function getTripLink($tripId, $tripAlias, $addIndex=null) {
		$appSettings = JBusinessUtil::getApplicationSettings();
		$appSettings->trip_url_naming = "trip";
	
		$itemid = JFactory::getApplication()->input->getInt('Itemid');
	
		$tripAlias = trim($tripAlias);
		$tripAlias = stripslashes(strtolower($tripAlias));
		$tripAlias = str_replace(" ", "-", $tripAlias);
	
		$conf = JBusinessUtil::getSiteConfig();
		$index ="";
		if (!JBusinessUtil::getSiteConfig()->sef_rewrite) {
			$index ="index.php/";
		}
	
		if (!$appSettings->enable_seo) {
			$tripLink = $tripId;
			if (JBusinessUtil::getSiteConfig()->sef) {
				$tripLink = $tripId;
			}
			$url = JRoute::_('index.php?option=com_jbusinessdirectory&view=trip&tripId='.$tripId, false, -1);
		} else {
			if ($appSettings->add_url_id == 1) {
				$tripLink = $tripId."-".htmlentities(urlencode($tripAlias));
			} else {
				$tripLink = htmlentities(urlencode($tripAlias));
			}
			
			$base = JBusinessUtil::getWebsiteURL(true).$index;
			$urlLngCodeStatus = self::getURLLanguageCodeStatus();
			if ($appSettings->add_url_language || $urlLngCodeStatus) {
				$langTag = self::getCurrentLanguageCode();
				$base.= $langTag."/";
			}
			$url = $base.$appSettings->trip_url_naming."/".$tripLink;
			
			$menuAlias = self::getCurrentMenuAlias();
			if ($appSettings->enable_menu_alias_url && !empty($menuAlias)) {
				$url = $base.$menuAlias."/".$appSettings->trip_url_naming."/".$tripLink;
			}
		}
	
		return $url;
	}

	/**
	 * Check if joomla 3 is used
	 *
	 * @return bool
	 */
	public static function isJoomla3() {
		$version = new JVersion();
		$versionA =  explode(".", $version->getShortVersion());
		if ($versionA[0] =="3") {
			return true;
		}
		return false;
	}

    /**
     * Include color picker based on Joomla version.
     */
    public static function includeColorPicker(){

        if(self::isJoomla3()){
            JHTML::_('behavior.colorpicker');
        }else{
            $wa = JFactory::getApplication()->getDocument()->getWebAssetManager();
            $wa->usePreset('minicolors')->useScript('field.color-adv');
        }

    }

	/**
	 * Truncate html text
	 *
	 * @param $text string text
	 * @param $length int length
	 * @param string $ending ending of the text
	 * @param bool $considerHtml
	 * @param bool $exact
	 *
	 * @return false|string
	 */
	public static function truncate($text, $length, $ending = '&hellip;', $considerHtml = true, $exact = false) {
		if ($considerHtml) {
			// if the plain text is shorter than the maximum length, return the whole text
			if (strlen(preg_replace('/<.*?>/', '', $text)) <= $length) {
				return $text;
			}
			// splits all html-tags to scanable lines
			preg_match_all('/(<.+?>)?([^<>]*)/s', $text, $lines, PREG_SET_ORDER);
			$total_length = strlen($ending);
			$open_tags = array();
			$truncate = '';
			foreach ($lines as $line_matchings) {
				// if there is any html-tag in this line, handle it and add it (uncounted) to the output
				if (!empty($line_matchings[1])) {
					// if it's an "empty element" with or without xhtml-conform closing slash
					if (preg_match('/^<(\s*.+?\/\s*|\s*(img|br|input|hr|area|base|basefont|col|frame|isindex|link|meta|param)(\s.+?)?)>$/is', $line_matchings[1])) {
						// do nothing
						// if tag is a closing tag
					} elseif (preg_match('/^<\s*\/([^\s]+?)\s*>$/s', $line_matchings[1], $tag_matchings)) {
						// delete tag from $open_tags list
						$pos = array_search($tag_matchings[1], $open_tags);
						if ($pos !== false) {
							unset($open_tags[$pos]);
						}
						// if tag is an opening tag
					} elseif (preg_match('/^<\s*([^\s>!]+).*?>$/s', $line_matchings[1], $tag_matchings)) {
						// add tag to the beginning of $open_tags list
						array_unshift($open_tags, strtolower($tag_matchings[1]));
					}
					// add html-tag to $truncate'd text
					$truncate .= $line_matchings[1];
				}
				// calculate the length of the plain text part of the line; handle entities as one character
				$content_length = strlen(preg_replace('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|[0-9a-f]{1,6};/i', ' ', $line_matchings[2]));
				if ($total_length+$content_length> $length) {
					// the number of characters which are left
					$left = $length - $total_length;
					$entities_length = 0;
					// search for html entities
					if (preg_match_all('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|[0-9a-f]{1,6};/i', $line_matchings[2], $entities, PREG_OFFSET_CAPTURE)) {
						// calculate the real length of all entities in the legal range
						foreach ($entities[0] as $entity) {
							if ($entity[1]+1-$entities_length <= $left) {
								$left--;
								$entities_length += strlen($entity[0]);
							} else {
								// no more characters left
								break;
							}
						}
					}
					$truncate .= substr($line_matchings[2], 0, $left+$entities_length);
					// maximum lenght is reached, so get off the loop
					break;
				} else {
					$truncate .= $line_matchings[2];
					$total_length += $content_length;
				}
				// if the maximum length is reached, get off the loop
				if ($total_length>= $length) {
					break;
				}
			}
		} else {
			if (strlen($text) <= $length) {
				return $text;
			} else {
				$truncate = substr($text, 0, $length - strlen($ending));
			}
		}
		// if the words shouldn't be cut in the middle...
		if (!$exact) {
			// ...search the last occurance of a space...
			$spacepos = strrpos($truncate, ' ');
			if (isset($spacepos)) {
				// ...and cut the text in this position
				$truncate = substr($truncate, 0, $spacepos);
			}
		}
		// add the defined ending to the text
		$truncate .= $ending;
		if ($considerHtml) {
			// close all unclosed html-tags
			foreach ($open_tags as $tag) {
				$truncate .= '</' . $tag . '>';
			}
		}
		return $truncate;
	}

	/**
	 * Generate the alias from title
	 *
	 * @param $title string title to get the alias
	 * @param $alias string alias
	 * @return string
	 */
	public static function getAlias($title, $alias) {
		if (empty($alias) || trim($alias) == '') {
			$alias = $title;
		}
		
		$alias = JApplicationHelper::stringURLSafe($alias);
		if (trim(str_replace('-', '', $alias)) == '') {
			$alias = JFactory::getDate()->format('Y-m-d-H-i-s');
		}
		
		return $alias;
	}

	/**
	 * Compose address based on address and city
	 *
	 * @param $address string address
	 * @param $city string city
	 * @return string
	 */
	public static function composeAddress($address, $city) {
		$result ="";
		if (!empty($address)) {
			$result .=$address;
		}
		
		if (!empty($address) && !empty($city)) {
			$result .=", ";
		}
		
		if (!empty($city)) {
			$result .=$city;
		}
		
		return $result;
	}

	/**
	 * Generate the address text
	 *
	 * @param $company object company details
	 * @return string|null
	 */
	public static function getAddressText($company) {
		$appSettings = JBusinessUtil::getApplicationSettings();
		$customAddress = $appSettings->custom_address;
		$address="";

		if(empty($company)){
			return;
		}

		$company->street_number = isset($company->street_number) ? $company->street_number : '';
		$company->postalCode    = isset($company->postalCode) ? $company->postalCode : '';
		if(!empty($company->postal_code)){
            $company->postalCode = $company->postal_code;
        }

		$company->province      = isset($company->province) ? $company->province : '';
		$company->address       = isset($company->address) ? $company->address : '';
		$company->county        = isset($company->county) ? $company->county : '';

        if(!empty($company->region)){
            $company->county = $company->region;
        }
		$company->city          = isset($company->city) ? $company->city : '';
		
		if (isset($company->publish_only_city) && $company->publish_only_city) {
			$addressParts = array($company->city,$company->county);
			if (!empty($company->countryId) && $appSettings->add_country_address == 1) {
				$addressParts[] = self::getCountry($company->countryId)->country_name;
			}
			
			$addressParts = array_filter($addressParts);
			foreach ($addressParts as $key=>$add) {
				if ($add == " ") {
					unset($addressParts[$key]);
				}
			}
			
			$addressParts = array_map('trim', $addressParts);
			$addressParts = implode(', ', $addressParts);
			$addressParts = trim($addressParts);
			$address = $addressParts;
			return $address;
		}

		if (!isset($company->street_number)) {
			$company->street_number = "";
		}

		if (!isset($company->area)) {
			$company->area = "";
		}

		if ($appSettings->limit_cities_regions == 1) {
			if (!empty($address) || !empty($customAddress)) {
				if (!empty($company->regions)) {
					$company->county = $company->regions[0]->name;
				}

				if (!empty($company->cities)) {
					$company->city   = $company->cities[0]->name;
				}
			}
		}

		$addressParts = array();
		switch ($appSettings->address_format) {
			case 1:
				$addressParts = array($company->street_number." ".$company->address, $company->area,$company->city." ".$company->postalCode,$company->county, $company->province);
				break;
			case 2:
				$addressParts = array($company->address." ".$company->street_number, $company->area,$company->city." ".$company->postalCode,$company->county, $company->province);
				break;
			case 3:
				$addressParts = array($company->street_number." ".$company->address, $company->area,$company->city,$company->county ." ".$company->postalCode, $company->province);
				break;
			case 4:
				$addressParts = array($company->address." ".$company->street_number, $company->area,$company->city,$company->county ." ".$company->postalCode, $company->province);
				break;
			case 5:
				$addressParts = array($company->street_number." ".$company->address, $company->area,$company->postalCode." ".$company->city,$company->county, $company->province);
				break;
			case 6:
				$addressParts = array($company->address." ".$company->street_number, $company->area,$company->postalCode." ".$company->city,$company->county, $company->province);
				break;
			case 7:
				$addressParts = array($company->postalCode." ".$company->province, $company->city, $company->area, $company->street_number);
				break;
			case 8:
				$customAddress = str_replace(ADDRESS_ADDRESS, $company->address, $customAddress);
				$customAddress = str_replace(ADDRESS_AREA, $company->area, $customAddress);
				$customAddress = str_replace(ADDRESS_CITY, $company->city, $customAddress);
				$customAddress = str_replace(ADDRESS_POSTAL_CODE, $company->postalCode, $customAddress);
				$customAddress = str_replace(ADDRESS_PROVINCE, $company->province, $customAddress);
				$customAddress = str_replace(ADDRESS_REGION, $company->county, $customAddress);
				$customAddress = str_replace(ADDRESS_STREET_NUMBER, $company->street_number, $customAddress);
				
				if (empty($company->address) && empty($company->area) && empty($company->city) && empty($company->postalCode) && empty($company->province) && empty($company->county) && empty($company->street_number)) {
					$customAddress="";
				}
				
				break;
		}
		
	  
		$addressParts = array_filter($addressParts);
		foreach ($addressParts as $key=>$add) {
			if ($add == " ") {
				unset($addressParts[$key]);
			}
		}
	   
		$addressParts = array_map('trim', $addressParts);
		$addressParts = implode(', ', $addressParts);
		$addressParts = trim($addressParts);
		$address = $addressParts;

		$countryName = "";
		if ($appSettings->add_country_address == 1) {
			if (!empty($address) || !empty($customAddress)) {
				if (!empty($company->country_name)) {
					if (!empty($address)) {
						$address .= ", " . $company->country_name;
					} else {
						$address = $company->country_name;
					}
					$countryName = $company->country_name;
				} elseif (!empty($company->countryName)) {
					if (!empty($address)) {
						$address .= ", " . $company->countryName;
					} else {
						$address = $company->countryName;
					}
					$countryName = $company->countryName;
                } elseif (!empty($company->country)) {
                    if (!empty($address)) {
                        $address .= ", " . $company->country;
                    } else {
                        $address = $company->country;
                    }
				} elseif (!empty($company->countryId)) {
					$country = self::getCountry($company->countryId);
					$countryName = !empty($country)?$country->country_name:"";
					if (!empty($address)) {
						$address .= ", " . $countryName;
					} else {
						$address = $countryName;
						;
					}
				}
			}
		}
		
		if ($appSettings->address_format == 8) {
			$customAddress = str_replace(ADDRESS_COUNTRY, $countryName, $customAddress);
			$address = $customAddress;
		}

		$address = explode(',', $address);
		$address = array_filter($address);
		foreach ($address as $key=>$add) {
			if ($add == " ") {
				unset($address[$key]);
			}
		}
		$address = implode(',', $address);
		$address = trim($address);

		if (empty($address)) {
			return null;
		}

		return $address;
	}

	/**
	 * Generate address based on city and county
	 *
	 * @param $item object item to get the details
	 * @return string
	 */
	public static function getShortAddress($item) {
		$address="";

		$city = "";
		if(!empty($item->city)){
			$city = '<span itemprop="addressLocality">'.$item->city.'</span>';
		}

		$county = "";
		if(!empty($item->county)){
			$county = '<span itemprop="addressRegion">'.$item->county.'</span>';
		}

		$addressParts = array($city,$county);
		$addressParts = array_filter($addressParts);
		
		if (!empty($addressParts)) {
			$address = implode(", ", $addressParts);
		}
		
		return $address;
	}

	/**
	 * Generate an address based on provided params
	 *
	 * @param $street_number
	 * @param $address
	 * @param $area
	 * @param $city
	 * @param $county
	 * @param $province
	 * @param $postalCode
	 * @return string|null
	 */
	public static function getLocationAddressText($street_number, $address, $area, $city, $county, $province, $postalCode, $showOnlyCity = false) {
		$locationItem = new stdClass();
		$locationItem->street_number = $street_number;
		$locationItem->address = $address;
		$locationItem->city = $city;
		$locationItem->county = $county;
		$locationItem->postalCode = $postalCode;
		$locationItem->province = $province;
		$locationItem->area = $area;
		$locationItem->publish_only_city = $showOnlyCity;
		
		return self::getAddressText($locationItem);
	}
	
	/**
	 * Get business listing category
	 *
	 * @param $company boolean company data
	 * @return int|mixed
	 */
	public static function getBusinessListingCategory($company) {
		$categoryId = 0;
		if (!empty($company->mainSubcategory)) {
			$categoryId = $company->mainSubcategory;
		} else {
			if (!empty($company->categories)) {
				$categoryId = $company->categories[0];
			}
		}
		
		return $categoryId;
	}
	
	/**
	 * Get business listing main category and retrieve the category path
	 * @param object $company company data
	 */
	public static function getBusinessCategoryPath($company) {
		$categoryId = self::getBusinessListingCategory($company);
		return self::getCategoryPath($categoryId);
	}

	/**
	 * Get the category path as an array of categories
	 *
	 * @param $categoryId int category id
	 * @return array
	 */
	public static function getCategoryPath($categoryId) {
		if (empty($categoryId)) {
			return array();
		}
		
		$categories = self::getCategories();
	
		$category = self::getCategory($categories, $categoryId);
		$path=array();
		if (!empty($category)) {
			$path[]=$category;
		
			while ($category->parent_id != 1) {
				if (!$category->parent_id) {
					break;
				}
				$category=self::getCategory($categories, $category->parent_id);
				$path[] = $category;
			}
				
			$path = array_reverse($path);
		}
		
		return $path;
	}

	/**
	 * Retrieve the categories from database or from the present cache
	 * @return mixed
	 */
	public static function getCategories() {
		$instance = JBusinessUtil::getInstance();
		
		if (!isset($instance->categories)) {
			JTable::addIncludePath(JPATH_ROOT.'/administrator/components/com_jbusinessdirectory/tables');
			$categoryTable =JTable::getInstance("Category", "JBusinessTable");
			$categories = $categoryTable->getAllCategories(0,true);
			$instance->categories = $categories;
		}
		return $instance->categories;
	}

	/**
	 * Get a category from cache based on category id
	 *
	 * @param $categories array categories array
	 * @param $categoryId int category id
	 * @return mixed|null
	 */
	public static function getCategory($categories, $categoryId) {
		if (empty($categories) || empty($categoryId)) {
			return null;
		}
		
		foreach ($categories as $category) {
			if ($category->id == $categoryId) {
				return $category;
			}
		}
		return null;
	}

	/**
	  * Get a category from cache based on category id
	 *
	 * @param $categoryId
	 * @return mixed|null
	 */
	public static function getCategoryItem($categoryId) {
		$categories = self::getCategories();
		if (empty($categories)) {
			return null;
		}
		
		foreach ($categories as $category) {
			if ($category->id == $categoryId) {
				return $category;
			}
		}
		
		return null;
	}

	/**
	 * Get the available languages on the CMS
	 *
	 * @return array
	 */
	public static function getLanguages() {
		$languages = JLanguageHelper::getKnownLanguages();
		
		$result = array();
		foreach ($languages as $key=>$language) {
			$name = isset($language["nativeName"])?$language["nativeName"]:$language["name"];
			if (strpos($name, "(")!==false) {
				$name = substr($name, 0, strpos($name, "(")-1);
			}
			if (!isset($result[$name])) {
				$result[$name]=$key;
			} else {
				$name = $language["name"];
				$result[$name]=$key;
			}
		}
		
		asort($result);
		return $result;
	}

	/**
	 * Get the current language tag
	 *
	 * @return string
	 */
	public static function getLanguageTag() {
		$lang = JFactory::getLanguage()->getTag();
		return $lang;
	}

	/**
	 * Get the current language code
	 *
	 * @return mixed
	 */
	public static function getCurrentLanguageCode() {
		$lang = JBusinessUtil::getLanguageTag();
		$lang = explode("-", $lang);
		return $lang[0];
	}

	/**
	 * Generate the list of available categories for drop down use
	 *
	 * @param $published
	 * @param null $type
	 * @param null $catId
	 * @param bool $showRoot
	 * @return mixed
	 */
	public static function getCategoriesOptions($published, $type = null, $catId = null, $showRoot = false, $onlyMain = false) {
		$db = JFactory::getDbo();
		$query = $db->getQuery(true)
		->select('a.id AS value, a.name AS text, a.level, a.published, a.parent_id')
		->from('#__jbusinessdirectory_categories AS a')
		->join('LEFT', $db->quoteName('#__jbusinessdirectory_categories') . ' AS b ON a.lft > b.lft AND a.rgt < b.rgt');
		
		if (!empty($catId)) {
			$query->join('LEFT', $db->quoteName('#__jbusinessdirectory_categories') . ' AS p ON p.id = ' . (int) $catId)
			->where('NOT(a.lft >= p.lft AND a.rgt <= p.rgt)');
		}
		
		if (($published)) {
			$query->where('a.published = 1');
		}


		if (($onlyMain)) {
			$query->where('a.parent_id = 1');
		}

		if (($type)) {
			$query->where('(a.type IN (0,' . (int) $type.'))');
		}
		
		if (!$showRoot) {
			$query->where('a.id >1');
		}
		
		$query->group('a.id, a.name, a.level, a.lft, a.rgt, a.parent_id, a.published')
		->order('a.lft ASC');
		
		$db->setQuery($query);
		$options = $db->loadObjectList();
		
		$categoryTranslations = JBusinessDirectoryTranslations::getInstance()->getCategoriesTranslations();
		
		// Pad the option text with spaces using depth level as a multiplier.
		for ($i = 0, $n = count($options); $i < $n; $i++) {
			if ($options[$i]->published == 1) {
				if (!empty($categoryTranslations[$options[$i]->value])) {
					$options[$i]->text = $categoryTranslations[$options[$i]->value]->name;
				}
				if ($showRoot) {
					$options[$i]->text = str_repeat('- ', $options[$i]->level) . $options[$i]->text;
				} else {
					$options[$i]->text = str_repeat('- ', $options[$i]->level-1) . $options[$i]->text;
				}
			} else {
				$options[$i]->text = str_repeat('- ', $options[$i]->level) . '[' . $options[$i]->text . ']';
			}
		}
		
		return $options;
	}


	/**
	 * Check if category is leaf
	 */

	public static function getLeafs($categories){
		$leafIds = array();
		if(empty($categories)){
			return $leafIds;
		}
	
		$parents = array();
		foreach($categories as $cat){
			$parents[$cat->parent_id] = $cat->parent_id;
		}

		foreach($categories as $cat){
			if(!isset($parents[$cat->value])){
				$leafIds[] = $cat->value;
			}
		}

		return $leafIds;
	}


	/**
	  * Generate the list of available companies for drop down use
	 *
	 * @param null $companyId
	 * @param null $userId
	 * @return mixed
	 */
	public static function getCompaniesOptions($companyId=null, $userId=null) {
		$db = JFactory::getDbo();
		$query = $db->getQuery(true)
		->select('id, name')
		->from('#__jbusinessdirectory_companies as c')
		->group('c.id')
		->order('c.name ASC');

		if (!empty($companyId)) {
			$query->where("c.id != $companyId");
		}
		
		if (!empty($userId)) {
			$query->where("c.userId = $userId");
		}
		
		$query->where("c.state = 1");

		$db->setQuery($query, 0, 50);
		
		$options = $db->loadObjectList();
		
		return $options;
	}

	/**
	 *  Generate the list of available events for drop down use
	 *
	 * If eventId is set then the event with that id will not be retrieved
	 * If userId is set then the function will retrieve only the events belonging to that user
	 *
	 * @param null $eventId event id
	 * @param null $userId user id
	 * @return mixed all events returned
	 * @since 5.3.1
	 */
	public static function getEventsOptions($eventId=null, $userId=null) {
		$db = JFactory::getDbo();
		$query = $db->getQuery(true)
			->select('id, name')
			->from('#__jbusinessdirectory_company_events as c')
			->group('c.id')
			->order('c.name ASC');

		if (!empty($eventId)) {
			$query->where("c.id != $eventId");
		}

		if (!empty($userId)) {
			$query->where("c.user_id = $userId");
		}

		$db->setQuery($query, 0, 20);

		$options = $db->loadObjectList();

		return $options;
	}

	/**
	 * Generate the list of available speakers for drop down use
	 *
	 * @return list of speakers
	 */
	public static function getSpeakersOptions() {
		$db = JFactory::getDbo();
		$query = $db->getQuery(true)
		->select('id AS value, name AS text')
		->from('#__jbusinessdirectory_conference_speakers')
		->group('id')
		->order('title ASC');

		$db->setQuery($query);
		$options = $db->loadObjectList();
		
		return $options;
	}

	/**
	 * Generate the list of available sessions for drop down use
	 *
	 * @return mixed
	 */
	public static function getSessionsOptions() {
		$db = JFactory::getDbo();
		$query = $db->getQuery(true)
		->select('id AS value, name AS text')
		->from('#__jbusinessdirectory_conference_sessions')
		->group('id')
		->order('name ASC');

		$db->setQuery($query);
		$options = $db->loadObjectList();
		
		return $options;
	}

	/**
	 * Generate the list of available conferences for drop down use
	 *
	 * @return mixed
	 */
	public static function getConferenceOptions() {
		$db = JFactory::getDbo();
		$query = $db->getQuery(true)
		->select('id AS value, name AS text')
		->from('#__jbusinessdirectory_conferences')
		->group('id')
		->order('name ASC');
		
		$db->setQuery($query);
		$options = $db->loadObjectList();
		
		return $options;
	}
	
	/**
	 * Get review question types
	 */
	public static function getReviewQuestiosnTypes() {
		$types = array();
		$type = new stdClass();
		$type->value = 0;
		$type->text = JTEXT::_("LNG_TEXT");
		$types[] = $type;
		$type = new stdClass();
		$type->value = 1;
		$type->text = JTEXT::_("LNG_YES_NO_QUESTION");
		$types[] = $type;
		$type = new stdClass();
		$type->value = 2;
		$type->text = JTEXT::_("LNG_RATING");
		$types[] = $type;
	
		return $types;
	}



	/**
	 * Get payment occurances options
	 */
	public static function getPaymentOccurances() {
		$types = array();

		for($i=2;$i<53;$i++){
			$type = new stdClass();
			$type->value = $i;
			$type->text = "$i";
			$types[] = $type;
		}
		
		return $types;
	}

	/**
	 * Convert an amount to the current price format from general settings
	 *
	 * @param $amount double price format
	 * @param $currencyId int currency id
	 * @param bool $skip_formating
	 * @return string
	 */
	public static function getPriceFormat($amount, $currencyId = null, $skip_formating = false) {
		$appSettings = JBusinessUtil::getApplicationSettings();
		$dec_point=".";
		$thousands_sep = ",";
		
		if ($appSettings->amount_separator==2) {
			$dec_point=",";
			$thousands_sep = ".";
		}
		
		$currencyString = $appSettings->currency_name;
		if ($appSettings->currency_display==2) {
			$currencyString = $appSettings->currency_symbol;
		}
		
		$amountString = $amount;
		if (!$skip_formating && is_numeric($amount)) {
			$amountString = number_format($amount, $appSettings->number_of_decimals, $dec_point, $thousands_sep);
		}

		if (!empty($currencyId)) {
			$currency = self::getCurrency($currencyId);
			$currencyString = $currency->currency_name;
			if ($appSettings->currency_display==2) {
				$currencyString = $currency->currency_symbol;
			}
		}
		
		if ($appSettings->currency_location==1) {
			if($appSettings->currency_display==2){
				$result = $currencyString.$amountString;
			}else{
				$result = $currencyString." ".$amountString;
			}
		} else {
			$result = $amountString." ".$currencyString;
		}

		return $result;
	}


	/**
	 * Convert an amount to the current price format from general settings
	 *
	 * @param $amount double price format
	 * @param $currencyId int currency id
	 * @param bool $skip_formating
	 * @return string
	 */
	public static function getHtmlPriceFormat($amount, $currencyId = null, $skip_formating = false) {
		$appSettings = JBusinessUtil::getApplicationSettings();
		$dec_point=".";
		$thousands_sep = ",";

		if(empty($amount)){
			return $amount;
		}

		if ($appSettings->amount_separator==2) {
			$dec_point=",";
			$thousands_sep = ".";
		}
		
		$currencyString = $appSettings->currency_name;
		if ($appSettings->currency_display==2) {
			$currencyString = $appSettings->currency_symbol;
		}

		if (!empty($currencyId)) {
			$currency = self::getCurrency($currencyId);
			$currencyString = $currency->currency_name;
			if ($appSettings->currency_display==2) {
				$currencyString = $currency->currency_symbol;
			}
		}
		
		$amountString = $amount;
		if (!$skip_formating) {
			$num = strval(number_format((float)$amount, $appSettings->number_of_decimals, $dec_point, $thousands_sep));
			$numParts = explode($dec_point, $num);
			
			$whole = $numParts[0];
			$frac = "";
			if(count($numParts) == 2){
				$frac = $numParts[1];
			}
			
			$amountString = '<span class="price-whole">'.$whole.'</span>';
			//$amountString .= '<span class="price-dec">'.$dec_point.'</span>';
			if(!empty($frac)){
				$amountString .= '<span class="price-fraction">'.$frac.'</span>';
			}
		}
		
		if ($appSettings->currency_location==1) {
			if($appSettings->currency_display==2){
				$result = $amountString = '<span class="price-symbol">'.$currencyString.'</span>'.$amountString;
			}else{
				$result = '<span class="price-currency">'.$currencyString.'</span>'." ".$amountString;
			}
		} else {
			$result = $amountString." ".'<span class="price-currency">'.$currencyString.'</span>';
		}

		$formattedPrice = '<span class="price-formatted">'.$result.'</span>';
		
		$amountString = $amount;
		if (!$skip_formating) {
			$amountString = number_format((float)$amount, $appSettings->number_of_decimals, $dec_point, $thousands_sep);
		}

		if (!empty($currencyId)) {
			$currency = self::getCurrency($currencyId);
			$currencyString = $currency->currency_name;
			if ($appSettings->currency_display==2) {
				$currencyString = $currency->currency_symbol;
			}
		}
		
		if ($appSettings->currency_location==1) {
			if($appSettings->currency_display==2){
				$result = $currencyString.$amountString;
			}else{
				$result = $currencyString." ".$amountString;
			}
		} else {
			$result = $amountString." ".$currencyString;
		}

		$result = $formattedPrice . '<span class="price-original">'.$result.'</span>';
		return $result;
	}

	/**
	 * Get the currency data based on id
	 *
	 * @param $currencyId int currency Id
	 * @return mixed
	 */
	public static function getCurrency($currencyId) {
		$instance = JBusinessUtil::getInstance();
		$varName = "currency".$currencyId;
		if (isset($instance->$varName)) {
			return $instance->$varName;
		}
		
		JTable::addIncludePath(JPATH_ROOT.'/administrator/components/com_jbusinessdirectory/tables');
		$currencyTable = JTable::getInstance("Currency", "JTable");
		$instance->$varName = $currencyTable->getCurrencyById($currencyId);
		
		return $instance->$varName;
	}

	/**
	 * Get price discount percentage
	 *
	 * @param $specialPrice
	 * @param $price
	 * @return string
	 */
	public static function getPriceDiscount($specialPrice, $price) {
		$percentChange = (1 - $specialPrice / $price) * 100;
		$discount =  number_format($percentChange,0);
		return $discount;
	}

	/**
	 * Convert price to mysql format
	 *
	 * @param $price string price
	 * @return string|string[]
	 */
	public static function convertPriceToMysql($price)
    {
        if (empty($price)) {
            return 0;
        }

        $appSettings = JBusinessUtil::getApplicationSettings();
        if ($appSettings->number_of_decimals == 0) {
            $price .=".00";
		}

		if (strpos($price, '.') && strpos($price, ',')) {
			if (strlen($price)>strrpos($price, ',') && strlen($price)>strrpos($price, '.')) {
				if (abs(strrpos($price, '.') - strrpos($price, ',')) == 4) {
					if (strrpos($price, '.') < strrpos($price, ',')) {
						$price = str_replace('.', '', $price);
						$pos = strrpos($price, ',');
						$price = substr_replace($price, '.', $pos, '1');
						$price = str_replace(',', '', $price);
					} else {
						$price = str_replace(',', '', $price);
						$pos = strrpos($price, '.');
						$price = substr_replace($price, ',', $pos, '1');
						$price = str_replace('.', '', $price);
						$price = str_replace(',', '.', $price);
					}
				} else {
					$price = str_replace('.', '', $price);
					$price = str_replace(',', '', $price);
				}
			} else {
				$price = str_replace('.', '', $price);
				$price = str_replace(',', '', $price);
			}
		} else {
			if (strlen($price) > (strrpos($price, ',')+1) || strlen($price) > (strrpos($price, '.')+1)) {
				if (substr_count($price, ',') > 1 || substr_count($price, '.') > 1) {
					if (strpos($price, '.')) {
						if (strlen($price) > (strrpos($price, '.')+1)) {
							$pos = strrpos($price, '.');
							$price = substr_replace($price, ',', $pos, '1');
							$price = str_replace('.', '', $price);
							$price = str_replace(',', '.', $price);
						} else {
							$price = str_replace('.', '', $price);
							$price = str_replace(',', '', $price);
						}
					} else {
						if (strlen($price) > (strrpos($price, ',')+1)) {
							$pos = strrpos($price, ',');
							$price = substr_replace($price, '.', $pos, '1');
							$price = str_replace(',', '', $price);
						} else {
							$price = str_replace('.', '', $price);
							$price = str_replace(',', '', $price);
						}
					}
				} else {
					$price = str_replace('.', '.', $price);
					$price = str_replace(',', '.', $price);
				}
			} else {
				$price = str_replace('.', '', $price);
				$price = str_replace(',', '', $price);
			}
		}
	  
		$price = str_replace(' ', '', $price);
		
		if (empty($price)) {
			$price = 0;
		} else {
			$price = doubleval($price);
		}

		return $price;
	}

	/**
	 * Convert price from mysql format
	 *
	 * @param $price string price
	 * @return string
	 */
	public static function convertPriceFromMysql($price) {
		$appSettings = JBusinessUtil::getApplicationSettings();
		$dec_point=".";
		$thousands_sep = ",";

		if ($appSettings->amount_separator==2) {
			$dec_point=",";
			$thousands_sep = ".";
		}

		$price = number_format($price, $appSettings->number_of_decimals, $dec_point, $thousands_sep);

		return $price;
	}

	/**
	 * Load extension language file based on the current language tag for admin area
	 */
	public static function loadAdminLanguage() {
		$language = JFactory::getLanguage();
		$language_tag 	= $language->getTag();
		//$language_tag = "nl-NL";
		$x = $language->load(
			'com_jbusinessdirectory',
			dirname(JPATH_ADMINISTRATOR.DS.'components'.DS.'com_jbusinessdirectory'.DS.'language'),
			$language_tag,
			true
		);
		
		/*$filename = JPATH_ADMINISTRATOR."/components/com_jbusinessdirectory/language/pl-PL/pl-PL.com_jbusinessdirectory.ini";
		dump($filename);
		$contents = file_get_contents($filename);
		$result = parse_ini_string($contents);
		dump($result);

		exit;*/
	}

	/**
	 * Load extension language file based on the current language tag for front-end
	 */
	public static function loadSiteLanguage() {
		$language = JFactory::getLanguage();
		$language_tag 	= $language->getTag();
		
		$x = $language->load(
			'com_jbusinessdirectory',
			dirname(JPATH_ADMINISTRATOR.DS.'components'.DS.'com_jbusinessdirectory'.DS.'language'),
			$language_tag,
			true
		);
		
		//load users language, needed for emails
		$x = $language->load(
			'com_users',
			dirname(JPATH_SITE.DS.'language'),
			$language_tag,
			true
		);
					
		$language_tag = str_replace("-", "_", $language->getTag());
		setlocale(LC_TIME, $language_tag.'.UTF-8');
	}
	
	
	/**
	 * Remove a file directory
	 *
	 * @param $dir
	 */
	public static function removeDirectory($dir) {
		if (is_dir($dir)) {
			$objects = scandir($dir);
			foreach ($objects as $object) {
				if ($object != "." && $object != "..") {
					if (filetype($dir."/".$object) == "dir") {
						rmdir($dir."/".$object);
					} else {
						unlink($dir."/".$object);
					}
				}
			}
			reset($objects);
			rmdir($dir);
		}
	}
	
	/**
	 * Removes a directory and all its content recursively
	 *
	 * @param $dir string path of the directory
	 *
	 * @return bool
	 *
	 * @since 5.1.5
	 */
	public static function recursiveRemoveDirectory($dir) {
		$files = array_diff(scandir($dir), array('.', '..'));
		foreach ($files as $file) {
			(is_dir("$dir/$file") && !is_link("$dir/$file")) ? self::recursiveRemoveDirectory("$dir/$file") : unlink("$dir/$file");
		}
		return rmdir($dir);
	}
	
	/**
	 * Convert a day to a String
	 * @param unknown_type $day
	 * @param unknown_type $abbr
	 */
	public static function dayToString($day, $abbr = false) {
		$date = new JDate();
		return addslashes($date->dayToString($day, $abbr));
	}
	
	/**
	 * Convert a month to a String
	 * @param unknown $month
	 * @param boolean $abbr
	 * @return string
	 */
	public static function monthToString($month, $abbr = false) {
		$date = new JDate();
		return addslashes($date->monthToString($month, $abbr));
	}
	
	
	/**
	 * Calculate the difference between 2 dates in days
	 *
	 * @param unknown $startData
	 * @param unknown $endDate
	 * @return number
	 */
	public static function getNumberOfDays($startData, $endDate) {
		$nrDays = floor((strtotime($endDate) - strtotime($startData)) / (60 * 60 * 24));
	
		return $nrDays;
	}
	
	/**
	 * Get the day of month from provided date
	 * @param unknown_type $date
	 */
	public static function getDayOfMonth($date) {
		if (empty($date)) {
			return "";
		}
		
		return date("j", strtotime($date));
	}

	/**
	 * Get the day of week from provided date
	 * @param unknown_type $date
	 */
	public static function getWeekDay($date) {
		if (empty($date)) {
			return "";
		}

		$date = JFactory::getDate($date);
		$dateS = $date->format('D');
		
		return $dateS;
	}

	/**
	 * Get month as string from provided date
	 * @param unknown_type $date
	 */
	public static function getMonth($date) {
		if (empty($date)) {
			return "";
		}
		$date = JFactory::getDate($date);
		return $date->format('M');
	}
	
	/**
	 * Get year from provided date
	 * @param unknown_type $date
	 * @return string
	 */
	public static function getYear($date) {
		if (empty($date)) {
			return "";
		}
		
		$date = JFactory::getDate($date);
		return $date->format('Y');
	}
	
	/**
	 * Include validation required files
	 */
	public static function includeValidation() {
		JBusinessUtil::enqueueStyle('libraries/validation-engine/validationEngine.jquery.css');
		$tag = JBusinessUtil::getCurrentLanguageCode();
		
		if (!file_exists(JPATH_COMPONENT_SITE.'/assets/libraries/validation-engine/jquery.validationEngine-'.$tag.'.js')) {
			$tag ="en";
		}
		
		JBusinessUtil::enqueueScript('libraries/validation-engine/jquery.validationEngine-'.$tag.'.js');
		JBusinessUtil::enqueueScript('libraries/validation-engine/jquery.validationEngine.js');
	}

	/**
	 * Calculate the elapsed time from a timestamp
	 *
	 * @param unknown_type $datetime
	 * @param unknown_type $full
	 * @return string
	 */
	public static function convertTimestampToAgo($datetime, $full = false) {
		$now = new DateTime;
		$ago = new DateTime($datetime);
		$diff = $now->diff($ago);

		$diff->w = floor($diff->d / 7);
		$diff->d -= $diff->w * 7;

		$string = array(
			'y' => 'year',
			'm' => 'month',
			'w' => 'week',
			'd' => 'day',
			'h' => 'hour',
			'i' => 'minute',
			's' => 'second',
		);
		foreach ($string as $k => &$v) {
			if ($diff->$k) {
				$v = $diff->$k . ' ' . $v . ($diff->$k > 1 ? 's' : '');
			} else {
				unset($string[$k]);
			}
		}

		if (!$full) {
			$string = array_slice($string, 0, 1);
		}
		return $string ? implode(', ', $string) . ' ago' : 'just now';
	}

	/**
	 * Remove files/images that are not linked anymore
	 * @param array $usedFiles
	 * @param unknown_type $rootFolder
	 * @param unknown_type $filesFolder
	 */
	public static function removeUnusedFiles(array $usedFiles, $rootFolder, $filesFolder) {
		$directoryPath = JBusinessUtil::makePathFile($rootFolder.$filesFolder);
		// $usedFiles -> array of the filename of the files
		// $filesFolder -> example: 'items/id/'
		// $rootFolder -> example: 'pictures'
		$usedFiles[]=JBusinessUtil::makePathFile($filesFolder)."index.html";
		
		foreach ($usedFiles as &$file) {
			$file = JBusinessUtil::makePathFile($file);
		}
		
		$allFiles = array();
		if (file_exists($directoryPath)) {
			foreach (scandir($directoryPath, 1) as $singleFile) {
				array_push($allFiles, JBusinessUtil::makePathFile($filesFolder.$singleFile));
			}
		}
		
		$unusedFiles = array_diff($allFiles, $usedFiles);
		
		foreach ($unusedFiles as $unusedFile) {
			if (is_file($rootFolder.$unusedFile)) {
				unlink($rootFolder.$unusedFile);
			}
		}
	}

	/**
	 * Move a file to a folder
	 *
	 * @param $picture_path string picture path
	 * @param $itemId int item id
	 * @param $oldId int old item id for the item
	 * @param $type int type of the file
	 * @return string|void
	 * @throws Exception
	 */
	public static function moveFile($picture_path, $itemId, $oldId, $type) {
		$path_new = JBusinessUtil::makePathFile(BD_PICTURES_UPLOAD_PATH .$type.($itemId)."/");
		
		//prepare photos
		$path_old = JBusinessUtil::makePathFile(BD_PICTURES_UPLOAD_PATH .$type.($oldId)."/");
		if (!empty($picture_path)) {
			$parts = explode("/", $picture_path);
			$oldId = $parts[2];
			$path_old = JBusinessUtil::makePathFile(BD_PICTURES_UPLOAD_PATH .$type.($oldId)."/");
		}
			
		$file_tmp = JBusinessUtil::makePathFile($path_old.basename($picture_path));
		//dump($file_tmp);
		if (!is_file($file_tmp)) {
			return;
		}
		//dump("is file");
		if (!is_dir($path_new)) {
			if (!@mkdir($path_new)) {
				throw( new Exception(JText::_("LNG_CANNOT_CREATE_DIRECTORY")) );
			}
		}
		
		//dbg(($path_old.basename($picture_path).",".$path_new.basename($picture_path)));
		// exit;
		if ($path_old.basename($picture_path) != $path_new.basename($picture_path)) {
			if ($oldId==0) {
				if (@rename($path_old.basename($picture_path), $path_new.basename($picture_path))) {
					$picture_path	 = $type.($itemId).'/'.basename($picture_path);
				//@unlink($path_old.basename($pic->room_picture_path));
				} else {
					throw( new Exception(JText::_("LNG_CANNOT_CHANGE_NAME")) );
				}
			} else {
				if (@copy($path_old.basename($picture_path), $path_new.basename($picture_path))) {
					$picture_path	 = $type.($itemId).'/'.basename($picture_path);
				//@unlink($path_old.basename($pic->room_picture_path));
				} else {
					throw( new Exception(JText::_("LNG_CANNOT_COPY_ITEM")) );
				}
			}
		}
		
		return $picture_path;
	}
	

	/**
	 * Get the type and thumbnail of the video based on the video url (Youtube, Vimeo and Tiktok supported).
	 *
	 * @param $url
	 * @return array()
	 */
	public static function getSoundDetails($url) {
		$data = array();

		// If it's a youtube video
		if (strpos($url, 'soundcloud') > 0) {
		
			//Get the JSON data of song details with embed code from SoundCloud oEmbed
			$getValues=file_get_contents('http://soundcloud.com/oembed?format=js&maxheight=300&url='.$url.'&iframe=true');
			//Clean the Json to decode
			$decodeiFrame=substr($getValues, 1, -2);
			//json decode to convert it as an array
			$jsonObj = json_decode($decodeiFrame);

			//$jsonObj->html = str_replace('height="400"', 'height="260"', $jsonObj->html);
			//$jsonObj->html = str_replace('visual=true', 'show_user=true', $jsonObj->html);

			$data = array(
				'iframe' => $jsonObj->html,
				'type' => 'soundcloud'
			);
		}
		// If it's a vimeo video
		elseif (strpos($url, 'spotify') > 0) {

			$trackURL = substr($url, 0, strpos($url, '?'));
			$trackURL = explode('/',$trackURL);
			$trackId = end($trackURL);

			$iframe = '<iframe style="border-radius:5px" src="https://open.spotify.com/embed/track/'.$trackId.'?utm_source=generator&theme=0" width="100%" height="360" frameBorder="0" allowfullscreen="" allow="autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture"></iframe>';
			$data = array(
				'iframe' => $iframe,
				'type' => 'spotify'
			);
		}

		return $data;
	}

	/**
	 * Get the type and thumbnail of the video based on the video url (Youtube, Vimeo and Tiktok supported).
	 *
	 * @param $url
	 * @return array()
	 */
	public static function getVideoDetails($url) {
		$data = array();

		$iframe = strpos($url, 'iframe');
		if (!empty($iframe)) { //if the $url is an iframe
			preg_match('/src="([^"]+)"/', $url, $match);
			if (isset($match[1])) {
				$url = $match[1];
			}
		}

		// If it's a youtube video
		if (strpos($url, 'youtu') > 0) {
			preg_match("/^(?:http(?:s)?:\/\/)?(?:www\.)?(?:m\.)?(?:youtu\.be\/|youtube\.com\/(?:(?:watch)?\?(?:.*&)?v(?:i)?=|(?:embed|v|vi|user)\/))([^\?&\"'>]+)/", $url, $matches);

			if (isset($matches[1])) {
				$id = $matches[1]; // We need the video ID to find the thumbnail
			} else {
				$id = "";
			}

			$thumbnail = 'https://img.youtube.com/vi/'.$id.'/0.jpg';
			
			$data = array(
				'url' => 'https://www.youtube-nocookie.com/embed/'.$id.'?rel=0',
				'type' => 'youtube',
				'video-id' => $id,
				'thumbnail' => $thumbnail
			);
		}
		// If it's a vimeo video
		elseif (strpos($url, 'vimeo') > 0) {
			preg_match("/https?:\/\/(?:www\.)?vimeo.com\/(?:channels\/(?:\w+\/)?|groups\/([^\/]*)\/videos\/|album\/(\d+)\/video\/|)(\d+)(?:$|\/|\?)/", $url, $matches);
			$id = $matches[3];
			$hash = unserialize(self::getURLData("https://vimeo.com/api/v2/video/".$id.".php"));
			$thumbnail = $hash[0]['thumbnail_large'];

			$data = array(
				'url' => 'https://vimeo.com/'.$id,
				'type' => 'vimeo',
				'video-id' => $id,
				'thumbnail' => $thumbnail
			);
		}
		// If it's a tiktok video
		elseif (strpos($url, 'tiktok') > 0) {
			preg_match("/https?:\/\/([^\.]+)?\.tiktok\.com\/([^\/]*)\/?video\/([^\/]*)\?(?:.*&)/", $url, $matches);
			$id = $matches[3];
			$thumbnail = "https://www.tiktok.com/api/img/?itemId=".$id."&location=0";

			$data = array(
				'url' => 'https://tiktok.com/embed/v2'.'/'.$id,
				'type' => 'tiktok',
				'video-id' => $id,
				'thumbnail' => $thumbnail
			);
		}
		// If it's not supported
		else {
			$data = array(
				'url' => 'https://www.youtube.com',
				'type' => 'unsupported',
				'thumbnail' => 'placehold.it/400x300?text=UNSUPPORTED+FORMAT'
			);
		}

		return $data;
	}
	
	/**
	 * Retrieve current version from manifest file
	 * @return  string versino number
	 */
	public static function getCurrentVersion() {
		$module = JComponentHelper::getComponent('com_jbusinessdirectory');
		$extension = JTable::getInstance('extension');
		$extension->load($module->id);
		$data = json_decode($extension->manifest_cache, true);
		return $data['version'];
	}

	/**
	 * Format the id of a booking to a specific format
	 *
	 * @param $bookingId
	 * @return string
	 */
	public static function formatBookingId($bookingId) {
		return str_pad($bookingId, LENGTH_ID_BOOKING, "0", STR_PAD_LEFT);
	}
	
	/**
	 * Method that gets the booking open date-times of a particular event, compares their values
	 * to the current time and returns true or false depending on whether the current date-time is
	 * considered as valid.
	 *
	 * @param $event	Object containing the booking dates and times
	 * @return bool		Boolean value
	 */
    public static function isBookingAvailable($event) {
        // Booking hours

        $startTime = $event->booking_open_time;
        $endTime = $event->booking_close_time;


		//set timezone and create a new object date time for that timezone
		$original = new DateTime("now", new DateTimeZone('GMT'));

		//TODO replace with JBusinessUtil::getCurrentTime
		$time_zone=intval($event->time_zone);
		$timezoneName = timezone_name_from_abbr("", $time_zone * 3600, false);
		$modified = $original->setTimezone(new DateTimezone($timezoneName));

		$currentTime = null;
		$currentTime = $modified->format('Y-m-d H:i:s');


        // Create Y-m-d H:i:s format if start/end hour is available, if not, 00:00:00 is set as start hour and 23:59:59 as end hour
        if (!empty($event->booking_open_time)) {
            $start = $event->booking_open_date . ' ' . $event->booking_open_time;
        } else {
            $start = $event->booking_open_date . ' 00:00:00';
        }

        if (!empty($event->booking_close_time)) {
            $end = $event->booking_close_date . ' ' . $event->booking_close_time;
        } else {
            $end = $event->booking_close_date . ' 23:59:59';
        }

        // If date is empty or set to 0, empty the $start and $end values
        if (self::emptyDate($event->booking_open_date)) {
            $start = '';
        }
        if (self::emptyDate($event->booking_close_date)) {
            $end = '';
        }

        if (!empty($start) || !empty($end)) {
            // Check the Booking Dates
            if (!empty($start) && !empty($end)) {

                if (strtotime($start) <= strtotime($currentTime) && strtotime($currentTime) < strtotime($end)) {
                    return true;
                } else {
                    return false;
                }
            } elseif (!empty($start)) {
                if (strtotime($start) <= strtotime($currentTime)) {
                    return true;
                } else {
                    return false;
                }
            } elseif (!empty($end)) {
                if (strtotime($end) > strtotime($currentTime)) {
                    return true;
                } else {
                    return false;
                }
            }
        }

        return true;
    }


    /**
	 * Checks if a date is empty or equal to the date equivalent of zero, and if so, returns true.
	 *
	 * @param $date
	 * @return bool
	 */
	public static function emptyDate($date) {
		if (!empty($date)) {
			if ($date == '0000-00-00' || $date == '00-00-0000' || $date == '0000-00-00 00:00:00' || $date == '00-00-0000 00:00:00') {
				return true;
			} else {
				return false;
			}
		} else {
			return true;
		}
	}

	/**
	 * Checks if the current date is inside the date interval determined by the $startDate and $endDate
	 *
	 * @param $startDate string containing the start Date of the interval
	 * @param $endDate	string containing the end Date of the interval
	 * @param $currentDate string containing the date that will be checked, null if the date that needs to be checked is the actual day
	 * @param bool|true $includeEndDate determines whether the end date
	 * will be included in the interval
	 * @param bool|true $allowEmptyBoundaries determines
	 * whether start or end date may be empty
	 * @return bool If date is in between the specified interval, true is returned.
	 * False is returned otherwise or if one of the boolean parameters condition is violated
	 *
	 * Note: if both start and end values are empty, and $allowEmptyBoundaries is set to true,
	 * true will be returned.
	 */
	public static function checkDateInterval($startDate, $endDate, $currentDate = null, $includeEndDate=true, $allowEmptyBoundaries=true) {
		if ($currentDate == null) {
			$currentDate = date("Y-m-d H:i:s");
		}

		if (!self::emptyDate($startDate) || $allowEmptyBoundaries) {
			$start = $startDate;
		} else {
			return false;
		}

		if (!self::emptyDate($endDate) || $allowEmptyBoundaries) {
			$end = $endDate;
		} else {
			return false;
		}

		if ($includeEndDate && !self::emptyDate($end)) {
			$end .= ' 23:59:59';
		}


		if (((strtotime($start) <= strtotime($currentDate)) || self::emptyDate($start))
			&& ((strtotime($currentDate) < strtotime($end)) || self::emptyDate($end))) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * Method that returns all dates between a provided date interval
	 *
	 * @param $first string First date of interval
	 * @param $last string Last date of interval
	 * @param string $step The iteration step (in days) between the dates
	 * @param string $output_format The output format of the dates
	 * @return array An array containing all the dates between the interval
	 */
	public static function getAllDatesInInterval($first, $last, $step = "+1 day", $output_format = "d-m-Y") {
		$dates = array();
		$current = strtotime($first);
		$last = strtotime($last);

		while ($current <= $last) {
			$dates[] = date($output_format, $current);
			$current = strtotime($step, $current);
		}

		return $dates;
	}


    /**
     * Get country based on id
     */
    public static function getCountryName($countryId){
        $instance = JBusinessUtil::getInstance();
        $countryName = "";

        if (empty($countryId)) {
            return "";
        }else{
            if(is_int($countryId)){
                $country =  $instance::getCountry($countryId);
                if(!empty($country)){
                    $countryName = $country->country_name;
                }
            }else{
                return "";
            }
        }

        return $countryName;
    }


   /**
	 * Get country based on id
	 */
	public static function getCountry($countryId) {
		$instance = JBusinessUtil::getInstance();

		if(empty($countryId)){
		    return null;
        }

		if(!isset($instance->countries)){
			$instance->countries = array();
		}

		if (!isset($instance->countries[$countryId])) {
			$db =JFactory::getDBO();
			$query = "select * from #__jbusinessdirectory_countries where id = $countryId ";
			$db->setQuery($query);
			$country = $db->loadObject();
			$instance->countries[$countryId] = $country;
		}
		
		return $instance->countries[$countryId];
	}

    /**
	 * Get country based on name
	 */
	public static function getCountryByName($country) {
		$instance = JBusinessUtil::getInstance();

		if(empty($country)){
		    return null;
        }
		
		if(!isset($instance->countries)){
			$instance->countries = array();
		}

		if (!isset($instance->countries[$country])) {
			$db =JFactory::getDBO();
			$query = "select * from #__jbusinessdirectory_countries where country_name = '$country' ";
			$db->setQuery($query);
			$countryObj = $db->loadObject();
			$instance->countries[$country] = $countryObj;
		}
		
		return $instance->countries[$country];
	}


	/**
	 * Get restricted countries
	 * @return array
	 */
	public static function getCountryRestriction() {
		$appSettings = JBusinessUtil::getApplicationSettings();
		$countries = $appSettings->country_ids;
		$countriesArray = array();
		if ($countries != '') {
			$countriesArray = explode(',', $countries);
		}

		$limitCountries = array();
		foreach ($countriesArray as $key => $value) {
			$country = JBusinessUtil::getCountry($value)->country_code;
			$limitCountries[] = $country;
		}
		return $limitCountries;
	}

	
	/**
	 * Get type name
	 */
	public static function getTypeName($typeId) {
		$db =JFactory::getDBO();
		$query = "select * from #__jbusinessdirectory_company_types where id = $typeId ";
		$db->setQuery($query);
		$type = $db->loadObject();
		
		return $type->name;
	}

	/**
	 * Validate order by field
	 * @return true if valid or false if not
	 */
	public static function validateOrderBy($orderBy, $allowedValues) {
		if(!empty($allowedValues)){
			foreach ($allowedValues as $item) {
				if ($orderBy == $item->value) {
					return true;
				}
			}
		}

		return false;
	}

	/**
	 * Get file size info
	 *
	 * @param unknown_type $bytes
	 * @param unknown_type $decimals
	 */
	public static function getReadableFilesize($bytes, $decimals = 2) {
		$sz = array('b', 'Kb', 'Mb', 'Gb', 'Tb');
		$factor = floor((strlen($bytes) - 1) / 3);
		return sprintf("%.{$decimals}f", $bytes / pow(1024, $factor)) . $sz[$factor];
	}


	/**
	 * convert all the following units ['B', 'KB', 'MB', 'GB', 'TB', 'PB'] to bytes
	 *
	 * @param $from string the value that will be converted to byte it will be of type 10B, 10MB etc
	 * @return float|int|null|string|string[]
	 * @since 4.9.5
	 */
	public static function convertToBytes($from) {
		$units = array('B', 'KB', 'MB', 'GB', 'TB', 'PB');
		$number = substr($from, 0, -2);
		$suffix = strtoupper(substr($from, -2));

		//B or no suffix
		if (is_numeric(substr($suffix, 0, 1))) {
			return preg_replace('/[^\d]/', '', $from);
		}

		$exponent = array_flip($units)[$suffix];
		if ($exponent === null) {
			return null;
		}

		return $number * (pow(1024, $exponent));
	}

	/**
	 * Get number of pdf pages
	 *
	 * @param  $pdfname
	 * @return number of pages
	 */
	public static function getNumberOfPdfPages($pdfname) {
        $pdftext = self::getURLData($pdfname);
		$num = preg_match_all("/\/Page\W/", $pdftext, $dummy);
		return $num;
	}

	/**
	 * Retrieve attachment properties
	 * @param unknown_type $attach
	 */
	public static function getAttachProperties($attachment) {
		$attachmentProperties = new stdClass();
		$fileProperties = pathinfo(BD_ATTACHMENT_PATH . $attachment->path);
		if (!isset($fileProperties['extension'])) {
			$fileProperties['extension'] = "FILE";
		}
		$attachmentProperties->fileProperties = $fileProperties;
		
		
		if (!empty($attachment->path)) {
			$realfile = BD_ATTACHMENT_UPLOAD_PATH . $attachment->path;
			$fsize = filesize($realfile);
			$attachmentProperties->size = JBusinessUtil::getReadableFilesize($fsize, 2);
		}

		if (strcasecmp($fileProperties['extension'], 'pdf') == 0  && !empty($attachment->path)) {
			$attachmentProperties->nrPages = JBusinessUtil::getNumberOfPdfPages(BD_ATTACHMENT_PATH . $attachment->path);
		} else {
			$attachmentProperties->nrPages = "";
		}

		switch (strtoupper($fileProperties['extension'])) {
			case "PDF":
				$attachmentProperties->icon = BD_ATTACHMENT_ICON_PATH . "pdf.png";
				break;
			case "BMP":
			case "GIF":
			case "JPEG":
			case "JPG":
			case "PNG":
				 $attachmentProperties->icon = BD_ATTACHMENT_ICON_PATH . "photo.png";
				break;
			case "DOC":
			case "DOCM":
			case "DOCX":
			case "GDOC":
				$attachmentProperties->icon = BD_ATTACHMENT_ICON_PATH . "doc.png";
				break;
			case "XLS":
			case "XLK":
			case "XLSX":
			case "XLR":
			case "XLT":
			case "XLW":
				 $attachmentProperties->icon = BD_ATTACHMENT_ICON_PATH . "xls.png";
				break;
			case "TXT":
				$attachmentProperties->icon = BD_ATTACHMENT_ICON_PATH . "txt.png";
				break;
			case "MP3":
			case "WMA":
			case "M4A":
			case "MP4A":
			case "AAC":
				$attachmentProperties->icon = BD_ATTACHMENT_ICON_PATH . "sound.png";
				break;
			default:
				$attachmentProperties->icon = BD_ATTACHMENT_ICON_PATH . "file.png";
		}

		return $attachmentProperties;
	}
	
	/**
	 * Upload file in a specified folder
	 *
	 * @param unknown_type $fileName
	 * @param unknown_type $data
	 * @param unknown_type $dest
	 * @return boolean|string|NULL
	 */
	public static function uploadFile($fileName, &$data, $dest) {
		//Retrieve file details from uploaded file, sent from upload form

		$file  = JFactory::getApplication()->input->files->get($fileName);
		//$file = JFactory::getApplication()->input->get($fileName, null, 'files', 'array');

		if ($file['name']=='') {
			return true;
		}
	
		//Import filesystem libraries. Perhaps not necessary, but does not hurt
		jimport('joomla.filesystem.file');
			
		//Clean up filename to get rid of strange characters like spaces etc
		$fileNameSrc = JFile::makeSafe($file['name']);
		$data[$fileName] =  $fileNameSrc;
	
		$src = $file['tmp_name'];
		$dest = $dest."/".$fileNameSrc;
	
		$result =  JFile::upload($src, $dest);
	
		if ($result) {
			return $dest;
		}
	
		return null;
	}

	/**
	 * Generate the direction URL for two waypoints and for the specified type of map
	 *
	 * @param $origin
	 * @param $destination
	 * @param $mapType int type of the map, default google
	 *
	 * @return string
	 */
	public static function getDirectionURL($origin, $destination = null, $mapType = null, $justOrigin = false) {
		$db = JFactory::getDbo();

		if (empty($mapType)) {
			$appSettings = JBusinessUtil::getApplicationSettings();
			$mapType     = $appSettings->map_type;
		}

		$source    = '';
		$dest      = '';
		$delimiter = '';
		$baseUrl   = '';
		if ($mapType == MAP_TYPE_GOOGLE) {
			$source = "";
			if (!empty($origin) && isset($origin["latitude"]) && isset($origin["longitude"])) {
				$source = "saddr=" . $db->escape($origin["latitude"]) . "," . htmlspecialchars($origin["longitude"]);
			}

			$dest = "";
			if (!empty($destination) && isset($destination->latitude) && isset($destination->longitude)) {
				$dest = "daddr=" . $db->escape($destination->latitude) . "," . $db->escape($destination->longitude);
			}

			if (!empty($source) && !empty($dest)) {
				$delimiter = "&";
			}

			$baseUrl = "https://maps.google.com?";
		} elseif ($mapType == MAP_TYPE_BING) {
			if (!empty($origin) && isset($origin["latitude"]) && isset($origin["longitude"])) {
				$source = "pos." . $db->escape($origin["latitude"]) . "_" . $db->escape($origin["longitude"]);
			}

			if (!empty($destination) && isset($destination->latitude) && isset($destination->longitude)) {
				$dest = "pos." . $db->escape($destination->latitude) . "_" . $db->escape($destination->longitude);
			}

			$delimiter = "";
			if (!empty($source) && !empty($dest)) {
				$delimiter = "~";
			}

			$baseUrl = "https://www.bing.com/maps?rtp=";
		} elseif ($mapType == MAP_TYPE_OSM) {
			if (!empty($origin) && isset($origin["latitude"]) && isset($origin["longitude"])) {
				$source = "route=" . $db->escape($origin["latitude"]) . "%2C" . $db->escape($origin["longitude"]);
			}

			if (!empty($destination) &&((isset($destination->latitude) && isset($destination->longitude)) || (is_array($destination) && isset($destination["latitude"]) && isset($destination["longitude"])) )) {

				$latitude = "";
				$longitude = "";

				if(!empty($destination->latitude)){
	            	$latitude = $destination->latitude;
	            	$longitude = $destination->longitude;
				}

				if(is_array($destination) && isset($destination["latitude"])){
					$latitude = $destination["latitude"];
					$longitude = $destination["longitude"];
				}

			    if (empty($origin)) {
			        $dest = "to=";
                } else {
			        $dest = "to=";
                }
                
				$dest .= $db->escape($latitude) . "%2C" . $db->escape($longitude);
			    $dest .= '#map=7/'.$db->escape($latitude).'/'.$db->escape($longitude);
			}

			$delimiter = "";
			if (!empty($source) && !empty($dest)) {
				$delimiter = "&";
			}

			if ($mapType == MAP_TYPE_OSM) {
				$delimiter = "";
			}

			$baseUrl = "https://www.openstreetmap.org/directions?engine=fossgis_osrm_car&";
		}

		$url = $baseUrl . $source . $delimiter . $dest;

		if ($justOrigin) {
			$url = $baseUrl . $source;
		}

		return $url;
	}

	/**
	 * Method that returns the translated name of the weekday for a
	 * given index that should range from 1-7
	 *
	 * @param $dayIndex int day of week index, should have values from 1 to 7
	 * @param $translate bool if false, days will not be translated (will stay in english)
	 * @return string the name of the weekday
	 * @return boolean false if the dayIndex is outside the required range
	 */
	public static function getWeekdayFromIndex($dayIndex, $translate=true) {
		if ($translate) {
			$days = array(
				1 => JText::_('LNG_MONDAY'),
				2 => JText::_('LNG_TUESDAY'),
				3 => JText::_('LNG_WEDNESDAY'),
				4 => JText::_('LNG_THURSDAY'),
				5 => JText::_('LNG_FRIDAY'),
				6 => JText::_('LNG_SATURDAY'),
				7 => JText::_('LNG_SUNDAY')
			);
		} else {
			$days = array(
				1 => 'Monday',
				2 => 'Tuesday',
				3 => 'Wednesday',
				4 => 'Thursday',
				5 => 'Friday',
				6 => 'Saturday',
				7 => 'Sunday'
			);
		}

		if ($dayIndex >= 1 && $dayIndex <= 7) {
			return $days[$dayIndex];
		} else {
			return false;
		}
	}

	/**
	 * Method that formats a timestamp duration or time period (minutes) into
	 * a better looking time text like: 'hh Hour(s) mm Minute(s) ss Second(s)'
	 *
	 * @param $time string containing the time in the hh:mm:ss format
	 * @param $timeFormat int 0-> 00:00:00, 1-> minutes
	 * @return string formatted time
	 */
	public static function formatTimePeriod($time, $timeFormat = 0) {

		if ($timeFormat == 0) {
			$temp = explode(':', $time);
			$hours = $temp[0];
			$minutes = $temp[1];
			$seconds = $temp[2];
		} elseif ($timeFormat == 1) {
			if ($time < 1) {
				return false;
			}

			$hours = floor($time / 60);
			$minutes = ($time % 60);
			$seconds = 0;
		}

		$resultTime = '';
		if (isset($hours) && $hours != '00' || $hours != '0') {
			$hoursText = (int)$hours > 1 ? JText::_('LNG_HOURS') : JText::_('LNG_HOUR');
			$resultTime .= (int)$hours . ' ' . $hoursText . ' ';
		}

		if (isset($minutes) && $minutes != '00' || $minutes != '0') {
			$minutesText = (int)$minutes > 1 ? JText::_('LNG_MINUTES') : JText::_('LNG_MINUTE');
			$resultTime .= (int)$minutes . ' ' . $minutesText . ' ';
		}

		if (isset($seconds) && $seconds != '00' || $seconds != '0') {
			$secondsText = (int)$seconds > 1 ? JText::_('LNG_SECONDS') : JText::_('LNG_SECOND');
			$resultTime .= (int)$seconds . ' ' . $secondsText . ' ';
		}

		return $resultTime;
	}


	/**
	 * Method that gets raw information about the vacations for a provider
	 * and organizes them into dates which will define the free days
	 *
	 * @param $vacationData object containing availability and break days information
	 *
	 * @return array organized array containing all the free days for a provider
	 */
	public static function processProviderVacationDays($vacationData) {
		$vacations    = array();
		$availability = explode(',', $vacationData->availability);
		$weekDays     = explode(',', $vacationData->breakDays);

		$availability = array_filter($availability);
		$weekDays = array_filter($weekDays);

		if (!empty($availability)) {
			$startDates = array();
			$endDates   = array();

			// get all start-end date pairs
			for ($i = 0; $i < count($availability); $i += 2) {
				$startDates[] = $availability[$i];
				$endDates[]   = $availability[$i + 1];
			}

			// get all dates between each startDate - endDate pair
			foreach ($startDates as $key => $val) {
				$dates     = self::getAllDatesInInterval($val, $endDates[$key], '+1 day', 'd-m-Y');
				$vacations = array_merge($vacations, $dates);
			}
		}

		$freeDays      = array();
		$addCurrentDay = false;
		foreach ($weekDays as $weekDay) {
			if (!empty($weekDay)) {
				// get the date of the nearest weekday at hand
				$day = date('d-m-Y', strtotime("next " . self::getWeekdayFromIndex($weekDay, false), strtotime(date('d-m-Y'))));

				if ($weekDay == date('N')) {
					$addCurrentDay = true;
				}

				// get all dates of the current weekday for the next 6 months
				$freeDays = array_merge($freeDays, self::getAllDatesInInterval($day, date('d-m-Y', strtotime("+6 months")), '+1 week', 'd-m-Y'));
			}
		}

		if ($addCurrentDay) {
			$freeDays[] = date('d-m-Y');
		}

		$vacations = array_merge($vacations, $freeDays);

		return $vacations;
	}

	/**
	 * Method that gets the raw information about the work and break hours for a provider and
	 * organizes them between the start and work hours (with an interval equal
	 * to the service duration) excluding the break hours intervals, into an array.
	 *
	 * @param $hours array containing all information about the work, break hours and the service duration
	 * @return array|bool organized array containing the available hours
	 */
	public static function processProviderAvailableHours($hours) {
		$workHours = array();
		$breakHours = array();
		foreach ($hours as $result) {
			if ($result->type == STAFF_WORK_HOURS) {
				$workHours["start_hour"] = $result->start_hour;
				$workHours["end_hour"] = $result->end_hour;
			} else {
				$breakHours["start_hour"][] =  $result->start_hour;
				$breakHours["end_hour"][] = $result->end_hour;
			}
		}

		if (!empty($breakHours)) {
			usort($breakHours["start_hour"], function ($a, $b) {
				return (strtotime($a) < strtotime($b)) ? -1 : 1;
			});
			usort($breakHours["end_hour"], function ($a, $b) {
				return (strtotime($a) < strtotime($b)) ? -1 : 1;
			});
		}

		$minutes = $hours[0]->duration;

		// if duration not available, default to 1 hour (60 minutes)
		if (empty($minutes)) {
			$minutes = 60;
		}

		if (!isset($workHours['start_hour'])) {
			return false;
		}

		$now = strtotime($workHours["start_hour"]);
		$end = strtotime($workHours["end_hour"]);

		$hours = array();
		$i = 0;
		while ($now < $end) {
			if (isset($breakHours["start_hour"][$i])) {
				if ($now >= strtotime($breakHours["start_hour"][$i]) && $now <= strtotime($breakHours["end_hour"][$i])) {
					$now = strtotime($breakHours["end_hour"][$i]);
					$i++;
				}
			}

			$hours[] = date('H:i:s', $now);
			$now = strtotime('+ '.$minutes.' minutes', $now);
		}

		$availableHours = array();

		foreach ($hours as $key=>$val) {
			if (isset($hours[$key])) {
				if (strtotime($val) < strtotime('12:00:00')) {
					$availableHours["morning"][] = $val;
				} elseif (strtotime($val) >= strtotime('12:00:00') && strtotime($val) < strtotime('18:00:00')) {
					$availableHours["afternoon"][] = $val;
				} elseif (strtotime($val) >= strtotime('18:00:00')) {
					$availableHours["evening"][] = $val;
				}
			}
		}

		return $availableHours;
	}

	/**
	 *
	 * Update company,offer or events data based on the default attributes
	 *
	 * @param $item object contain all the company data
	 * @param $defaultAttribute array with the application configuration
	 * @return mixed the updated object of company,offer or events
	 */
	public static function updateItemDefaultAtrributes(&$item, $defaultAttribute) {
		if (empty($item)) {
			return;
		}
		
		if (isset($item->website) && !empty($item->website)) {
			$item->website           = $defaultAttribute["website"]          !=ATTRIBUTE_NOT_SHOW?$item->website:"";
		}
		if (isset($item->keywords) && !empty($item->keywords)) {
			$item->keywords          = $defaultAttribute["keywords"]         !=ATTRIBUTE_NOT_SHOW?$item->keywords:"";
		}
		if (isset($item->categories) && !empty($item->categories)) {
			$item->categories        = $defaultAttribute["category"]         !=ATTRIBUTE_NOT_SHOW?$item->categories:"";
		}
		if (isset($item->logoLocation) && !empty($item->logoLocation)) {
			$item->logoLocation      = $defaultAttribute["logo"]             !=ATTRIBUTE_NOT_SHOW?$item->logoLocation:"";
		}
		if (isset($item->street_number) && !empty($item->street_number)) {
			$item->street_number     = $defaultAttribute["street_number"]    !=ATTRIBUTE_NOT_SHOW?$item->street_number:"";
		}
		if (isset($item->address) && !empty($item->address)) {
			$item->address           = $defaultAttribute["address"]          !=ATTRIBUTE_NOT_SHOW?$item->address:"";
		}
		if (isset($item->city) && !empty($item->city)) {
			$item->city              = $defaultAttribute["city"]             !=ATTRIBUTE_NOT_SHOW?$item->city:"";
		}
		if (isset($item->county) && !empty($item->county)) {
			$item->county            = $defaultAttribute["region"]           !=ATTRIBUTE_NOT_SHOW?$item->county:"";
		}
		if (isset($item->countryId) && !empty($item->countryId)) {
			$item->countryId         = $defaultAttribute["country"]          !=ATTRIBUTE_NOT_SHOW?$item->countryId:"";
		}
		if (isset($item->countryName) && !empty($item->countryName)) {
			$item->countryName       = $defaultAttribute["country"]          !=ATTRIBUTE_NOT_SHOW?$item->countryName:"";
		}
		if (isset($item->country_name) && !empty($item->country_name)) {
			$item->country_name      = $defaultAttribute["country"]          !=ATTRIBUTE_NOT_SHOW?$item->country_name:"";
		}
		if (isset($item->postalCode) && !empty($item->postalCode)) {
			$item->postalCode        = $defaultAttribute["postal_code"]      !=ATTRIBUTE_NOT_SHOW?$item->postalCode:"";
		}
		if (isset($item->phone) && !empty($item->phone)) {
			$item->phone             = $defaultAttribute["phone"]            !=ATTRIBUTE_NOT_SHOW?$item->phone:"";
		}
		if (isset($item->mobile) && !empty($item->mobile)) {
			$item->mobile            = $defaultAttribute["mobile_phone"]     !=ATTRIBUTE_NOT_SHOW?$item->mobile:"";
		}
		if (isset($item->fax) && !empty($item->fax)) {
			$item->fax               = $defaultAttribute["fax"]              !=ATTRIBUTE_NOT_SHOW?$item->fax:"";
		}
		if (isset($item->email) && !empty($item->email)) {
			$item->email             = $defaultAttribute["email"]            !=ATTRIBUTE_NOT_SHOW?$item->email:"";
		}
		if (isset($item->short_description) && !empty($item->short_description)) {
			$item->short_description = $defaultAttribute["short_description"]!=ATTRIBUTE_NOT_SHOW?$item->short_description:"";
		}
		if (isset($item->province) && !empty($item->province)) {
			$item->province          = $defaultAttribute["province"]         !=ATTRIBUTE_NOT_SHOW?$item->province:"";
		}
		if (isset($item->typeName) && !empty($item->typeName)) {
			$item->typeName          = $defaultAttribute["type"]             !=ATTRIBUTE_NOT_SHOW?$item->typeName:"";
		}
		if (isset($item->longitude) && !empty($item->longitude)) {
			$item->longitude         = $defaultAttribute["map"]              !=ATTRIBUTE_NOT_SHOW?$item->longitude:"";
		}
		if (isset($item->latitude) && !empty($item->latitude)) {
			$item->latitude          = $defaultAttribute["map"]              !=ATTRIBUTE_NOT_SHOW?$item->latitude:"";
		}
		if (isset($item->taxCode) && !empty($item->taxCode)) {
			$item->taxCode           = $defaultAttribute["tax_code"]         !=ATTRIBUTE_NOT_SHOW?$item->taxCode:"";
		}
		if (isset($item->comercialName) && !empty($item->comercialName)) {
			$item->comercialName     = $defaultAttribute["comercial_name"]   !=ATTRIBUTE_NOT_SHOW?$item->comercialName:"";
		}
		if (isset($item->slogan) && !empty($item->slogan)) {
			$item->slogan            = $defaultAttribute["slogan"]           !=ATTRIBUTE_NOT_SHOW?$item->slogan:"";
		}
		if (isset($item->description) && !empty($item->description)) {
			$item->description       = $defaultAttribute["description"]      !=ATTRIBUTE_NOT_SHOW?$item->description:"";
		}
		if (isset($item->pictures) && !empty($item->pictures)) {
			$item->pictures          = $defaultAttribute["pictures"]         !=ATTRIBUTE_NOT_SHOW?$item->pictures:array();
		}
		if (isset($item->videos) && !empty($item->videos)) {
			$item->videos            = $defaultAttribute["video"]            !=ATTRIBUTE_NOT_SHOW?$item->videos:array();
		}
		if (isset($item->facebook) && !empty($item->facebook)) {
			$item->facebook          = $defaultAttribute["social_networks"]  !=ATTRIBUTE_NOT_SHOW && $defaultAttribute["facebook"] !=ATTRIBUTE_NOT_SHOW?$item->facebook:"";
		}
		if (isset($item->twitter) && !empty($item->twitter)) {
			$item->twitter           = $defaultAttribute["social_networks"]  !=ATTRIBUTE_NOT_SHOW && $defaultAttribute["twitter"] !=ATTRIBUTE_NOT_SHOW?$item->twitter:"";
		}
		if (isset($item->googlep) && !empty($item->googlep)) {
			$item->googlep           = $defaultAttribute["social_networks"]  !=ATTRIBUTE_NOT_SHOW?$item->googlep:"";
		}
		if (isset($item->skype) && !empty($item->skype)) {
			$item->skype             = $defaultAttribute["social_networks"]  !=ATTRIBUTE_NOT_SHOW && $defaultAttribute["skype"] !=ATTRIBUTE_NOT_SHOW?$item->skype:"";
		}
		if (isset($item->linkedin) && !empty($item->linkedin)) {
			$item->linkedin          = $defaultAttribute["social_networks"]  !=ATTRIBUTE_NOT_SHOW && $defaultAttribute["linkedin"] !=ATTRIBUTE_NOT_SHOW?$item->linkedin:"";
		}
		if (isset($item->youtube) && !empty($item->youtube)) {
			$item->youtube           = $defaultAttribute["social_networks"]  !=ATTRIBUTE_NOT_SHOW && $defaultAttribute["youtube"] !=ATTRIBUTE_NOT_SHOW?$item->youtube:"";
		}
		if (isset($item->instagram) && !empty($item->instagram)) {
			$item->instagram         = $defaultAttribute["social_networks"]  !=ATTRIBUTE_NOT_SHOW && $defaultAttribute["instagram"] !=ATTRIBUTE_NOT_SHOW?$item->instagram:"";
		}
		if (isset($item->pinterest) && !empty($item->pinterest)) {
			$item->pinterest         = $defaultAttribute["social_networks"]  !=ATTRIBUTE_NOT_SHOW && $defaultAttribute["pinterest"] !=ATTRIBUTE_NOT_SHOW?$item->pinterest:"";
		}
		if (isset($item->whatsapp) && !empty($item->whatsapp)) {
			$item->whatsapp          = $defaultAttribute["social_networks"]  !=ATTRIBUTE_NOT_SHOW && $defaultAttribute["whatsapp"] !=ATTRIBUTE_NOT_SHOW?$item->whatsapp:"";
		}
		if (isset($item->contacts) && !empty($item->contacts)) {
			$item->contacts          = $defaultAttribute["contact_person"]   !=ATTRIBUTE_NOT_SHOW?$item->contacts:array();
		}
		if (isset($item->attachments) && !empty($item->attachments)) {
			$item->attachments       = $defaultAttribute["attachments"]      !=ATTRIBUTE_NOT_SHOW?$item->attachments:array();
		}
		if (isset($item->custom_tab_name) && !empty($item->custom_tab_name)) {
			$item->custom_tab_name   = $defaultAttribute["custom_tab"]       !=ATTRIBUTE_NOT_SHOW?$item->custom_tab_name:"";
		}
		if (isset($item->custom_tab_content) && !empty($item->custom_tab_content)) {
			$item->custom_tab_content= $defaultAttribute["custom_tab"]       !=ATTRIBUTE_NOT_SHOW?$item->custom_tab_content:"";
		}
		if (isset($item->business_hours) && !empty($item->business_hours)) {
			$item->business_hours    = $defaultAttribute["opening_hours"]    !=ATTRIBUTE_NOT_SHOW?$item->business_hours:array();
		}
		if (isset($item->notes_hours) && !empty($item->notes_hours)) {
			$item->notes_hours       = $defaultAttribute["opening_hours"]    !=ATTRIBUTE_NOT_SHOW?$item->notes_hours:"";
		}
		if (isset($item->meta_title) && !empty($item->meta_title)) {
			$item->meta_title        = $defaultAttribute["metadata_information"]!=ATTRIBUTE_NOT_SHOW?$item->meta_title:"";
		}
		if (isset($item->meta_description) && !empty($item->meta_description)) {
			$item->meta_description  = $defaultAttribute["metadata_information"]!=ATTRIBUTE_NOT_SHOW?$item->meta_description:"";
		}
		if (isset($item->meta_keywords) && !empty($item->meta_keywords)) {
			$item->meta_keywords     = $defaultAttribute["metadata_information"]!=ATTRIBUTE_NOT_SHOW?$item->meta_keywords:"";
		}
		if (isset($item->publish_start_date) && !empty($item->publish_start_date)) {
			$item->publish_start_date= $defaultAttribute["publish_dates"]    !=ATTRIBUTE_NOT_SHOW?$item->publish_start_date:"";
		}
		if (isset($item->publish_end_date) && !empty($item->publish_end_date)) {
			$item->publish_end_date  = $defaultAttribute["publish_dates"]    !=ATTRIBUTE_NOT_SHOW?$item->publish_end_date:"";
		}
		if (isset($item->area) && !empty($item->area)) {
			$item->area              = $defaultAttribute["area"]             !=ATTRIBUTE_NOT_SHOW?$item->area:"";
		}
		if (isset($item->business_cover_image) && !empty($item->business_cover_image)) {
			$item->business_cover_image= $defaultAttribute["cover_image"]    !=ATTRIBUTE_NOT_SHOW?$item->business_cover_image:"";
		}
		if (isset($item->contact_phone) && !empty($item->contact_phone)) {
			$item->contact_phone     = $defaultAttribute["phone"]            !=ATTRIBUTE_NOT_SHOW?$item->contact_phone:"";
		}
		if (isset($item->contact_email) && !empty($item->contact_email)) {
			$item->contact_email     = $defaultAttribute["email"]            !=ATTRIBUTE_NOT_SHOW?$item->contact_email:"";
		}
		if (isset($item->establishment_year) && !empty($item->establishment_year)) {
			$item->establishment_year= $defaultAttribute["establishment_year"]!=ATTRIBUTE_NOT_SHOW?$item->establishment_year:"";
		}
		if (isset($item->employees) && !empty($item->employees)) {
			$item->employees         = $defaultAttribute["employees"]        !=ATTRIBUTE_NOT_SHOW?$item->employees:"";
		}
		if (isset($item->ad_image) && !empty($item->ad_image)) {
			$item->ad_image          = $defaultAttribute["ad_images"]        !=ATTRIBUTE_NOT_SHOW?$item->ad_image:"";
		}
		if (isset($item->price_text) && !empty($item->price_text)) {
			$item->price_text        = $defaultAttribute["price_text"]       !=ATTRIBUTE_NOT_SHOW?$item->price_text:"";
		}
		if (isset($item->related_listing) && !empty($item->related_listing)) {
			$item->related_listing   = $defaultAttribute["related_listing"]  !=ATTRIBUTE_NOT_SHOW?$item->related_listing:"";
		}
		if (isset($item->price) && !empty($item->price)) {
			$item->price  			 = $defaultAttribute["price"] 			 !=ATTRIBUTE_NOT_SHOW?$item->price:"";
		}
		if (isset($item->enable_subscription) && !empty($item->enable_subscription)) {
			$item->enable_subscription = $defaultAttribute["enable_subscription"]  	 !=ATTRIBUTE_NOT_SHOW?$item->enable_subscription:"";
		}
		if (isset($item->total_tickets) && !empty($item->total_tickets)) {
			$item->total_tickets   	 = $defaultAttribute["total_tickets"]  	 !=ATTRIBUTE_NOT_SHOW?$item->total_tickets:"";
		}
		if (isset($item->time_zone) && !empty($item->time_zone)) {
			$item->time_zone   	     = $defaultAttribute["time_zone"]  	  	 !=ATTRIBUTE_NOT_SHOW?$item->time_zone:"";
		}
		if (isset($item->booking_open_date) && !empty($item->booking_open_date)) {
			$item->booking_open_date   	 = $defaultAttribute["booking_dates"]  	 !=ATTRIBUTE_NOT_SHOW?$item->booking_open_date:"";
		}
		if (isset($item->booking_close_date) && !empty($item->booking_close_date)) {
			$item->booking_close_date   	 = $defaultAttribute["booking_dates"]  	 !=ATTRIBUTE_NOT_SHOW?$item->booking_close_date:"";
		}

		return $item;
	}

	/**
	 * This function get all the default business attribute configuration on general settings
	 *
	 * @return array containing all the default attribute and their configuration
	 */
	public static function getAttributeConfiguration($attrType) {
		if (empty($attrType) || !isset($attrType)) {
			$attrType = DEFAULT_ATTRIBUTE_TYPE_LISTING;
		}
		
		$instance = JBusinessUtil::getInstance();
		$varName = "attributeConfiguration".$attrType;
		if (isset($instance->$varName)) {
			return $instance->$varName;
		}
		
		JTable::addIncludePath(JPATH_ROOT.'/administrator/components/com_jbusinessdirectory/tables');
		$defaultAttributesTable = JTable::getInstance('DefaultAttributes', 'Table');
		$attributesConfiguration = $defaultAttributesTable->getAttributesConfiguration($attrType);
		$defaultAtrributes= array();
		if (isset($attributesConfiguration) && count($attributesConfiguration)>0) {
			foreach ($attributesConfiguration as $attrConfig) {
				$defaultAtrributes[$attrConfig->name] = $attrConfig->config;
			}
		}
		
		$instance->$varName = $defaultAtrributes;

		return $defaultAtrributes;
	}

    /**
     * Method that returns a complex array organized in a way that it may
     * be simply used in a view to display the work and break hours.
     *
     * The main array will have 7 objects, one for each day of the week.
     * Each of these objects will contain the name of the day, and the
     * break and work hours for that particular day.
     *
     * @param $workHours array containing the work hours for all days of the week
     * @param $breakHours array containing the break hours for all days of the week
     *
     * @return array
     */
    public static function getWorkingDays($workHours, $breakHours, $startDate=null, $endDate=null) {
        $workingDays = array();

        if(empty($startDate)) {
            for ($i = 1; $i <= 7; $i++) {
                $day = self::getWorkingDay($workHours, $breakHours, $i);

                $day->name = self::getWeekdayFromIndex($i);
                $workingDays[$i] = $day;
            }
        }else{
            $date = strtotime($startDate);
            $index = 1;
            while($date <= strtotime($endDate)){
                $day = self::getWorkingDay($workHours, $breakHours, $index);

                $day->name = self::getDateGeneralFormat(date("Y-m-d",$date));
                $workingDays[$index] = $day;
                $index++;
                $date = strtotime("+1 day", $date);
            }
        }

        return $workingDays;
    }


    /**
     * Build the day working structure
     *
     * @param $workHours
     * @param $breakHours
     * @return stdClass
     */
    public static function getWorkingDay($workHours, $breakHours, $index){
        $day = new stdClass();

        $day->workHours['id'] = '';
        $day->workHours['status'] = '';
        $day->workHours['start_time'] = '';
        $day->workHours['end_time'] = '';
        if (!empty($workHours) || !empty($breakHours)) {
            // Arrange the working hours
            if (isset($workHours[$index - 1])) {
                $day->workHours['start_time'] = $workHours[$index - 1]->startHours;
                $day->workHours['end_time'] = $workHours[$index - 1]->endHours;
                $day->workHours['id'] = $workHours[$index - 1]->periodIds;
                $day->workHours['status'] = $workHours[$index - 1]->statuses;
            }

            // Arrange the break hours
            if (!empty($breakHours[$index])) {
                $day->breakHours = array();
                $startHours = explode(',', $breakHours[$index]->startHours);
                $endHours = explode(',', $breakHours[$index]->endHours);
                $breakIds = explode(',', $breakHours[$index]->periodIds);
                $n = count($startHours);
                if ($n > 0) {
                    for ($j = 0; $j < $n; $j++) {
                        $day->breakHours['start_time'][$j] = $startHours[$j];
                        $day->breakHours['end_time'][$j] = $endHours[$j];
                        $day->breakHours['id'][$j] = $breakIds[$j];
                    }
                } else {
                    $day->breakHours['start_time'][] = null;
                    $day->breakHours['end_time'][] = null;
                }
            }
        } else {
            $day->workHours['start_time'] = null;
            $day->workHours['end_time'] = null;
            $day->workHours['id'] = null;
            $day->breakHours[0]['start_time'] = null;
            $day->breakHours[0]['end_time'] = null;
        }

        return $day;
    }

	/**
	 * This function generate an array with all the timezones to be used for a good user experience
	 *
	 * @return array contain all the timezones
	 */
	public static function timeZonesList() {
		return $timezoneTable = array(
			"-11:00" => "(GMT -11:00) Midway Island, Samoa",
			"-10:00" => "(GMT -10:00) Hawaii",
			"-09:30" => "(GMT -9:30) Marquesas Islands",
			"-09:00" => "(GMT -9:00) Alaska",
			"-08:00" => "(GMT -8:00) Pacific Time (US &amp; Canada)",
			"-07:00" => "(GMT -7:00) Mountain Time (US &amp; Canada)",
			"-06:00" => "(GMT -6:00) Central Time (US &amp; Canada), Mexico City",
			"-05:00" => "(GMT -5:00) Eastern Time (US &amp; Canada), Bogota, Lima",
			"-04:00" => "(GMT -4:00) Atlantic Time (Canada), Caracas, La Paz",
			"-03:30" => "(GMT -3:30) Newfoundland",
			"-03:00" => "(GMT -3:00) Brazil, Buenos Aires, Georgetown",
			"-02:00" => "(GMT -2:00) Noronha, South Georgia",
			"-01:00" => "(GMT -1:00) Azores, Cape Verde Islands",
			"+00:00" => "(GMT) Western Europe Time, London, Lisbon, Casablanca",
			"+01:00" => "(GMT +1:00) BST, Brussels, Copenhagen, Madrid, Paris",
			"+02:00" => "(GMT +2:00) Kaliningrad, South Africa, Helsinki, Bucharest, Athens, Jerusalem",
			"+03:00" => "(GMT +3:00) Baghdad, Riyadh, Moscow, St. Petersburg",
			"+04:00" => "(GMT +4:00) Abu Dhabi, Muscat, Baku, Tbilisi",
			"+04:30" => "(GMT +4:30) Kabul",
			"+05:00" => "(GMT +5:00) Ekaterinburg, Islamabad, Karachi, Tashkent",
			"+05:30" => "(GMT +5:30) Bombay, Calcutta, Madras, New Delhi",
			"+05:45" => "(GMT +5:45) Kathmandu",
			"+06:00" => "(GMT +6:00) Astana, Dhaka, Vostok",
			"+06:30" => "(GMT +6:30) Rangoon, Cocos Islands",
			"+07:00" => "(GMT +7:00) Bangkok, Hanoi, Jakarta",
			"+08:00" => "(GMT +8:00) Beijing, Perth, Hong Kong, Kuala Lumpur",
			"+08:45" => "(GMT +8:45) Eucla",
			"+09:00" => "(GMT +9:00) Tokyo, Seoul, Osaka, Sapporo, Yakutsk",
			"+09:30" => "(GMT +9:30) Adelaide, Darwin",
			"+10:00" => "(GMT +10:00) Melbourne, Brisbane, Canberra, Guam, Vladivostok",
			"+10:30" => "(GMT +10:30) Lord Howe Island",
			"+11:00" => "(GMT +11:00) Sakhalin, Chokurdakh, Solomon Is. Island",
			"+12:00" => "(GMT +12:00) Auckland, Wellington, Fiji, Kamchatka",
			"+12:45" => "(GMT +12:45) Chatham Islands",
			"+13:00" => "(GMT +13:00) Samoa, Tongatapu",
			"+14:00" => "(GMT +14:00) Kiritimati Island"
		);
	}

	/**
	 * Get all checklist elements organized in an array, each element
	 * having a name and status field. Status field is set to 0 by
	 * default.
	 *
	 * @param $type int business->1 offer->2 event->3
	 * @return array checklist array
	 */
	public static function getChecklist($type=1) {
		$checklist = array();
		$checklist['description'] = new stdClass();
		$checklist['address'] = new stdClass();

		// Business fields
		if ($type == 1) {
			$checklist['email'] = new stdClass();
			$checklist['keywords'] = new stdClass();
			$checklist['website'] = new stdClass();
			$checklist['logo'] = new stdClass();
			$checklist['cover_image'] = new stdClass();
			$checklist['social_networks'] = new stdClass();
		}
		// Offer fields
		elseif ($type == 2) {
			$checklist['duration'] = new stdClass();
			$checklist['pictures'] = new stdClass();
			$checklist['price'] = new stdClass();
		}
		// Event fields
		elseif ($type == 3) {
			$checklist['email'] = new stdClass();
			$checklist['duration'] = new stdClass();
			$checklist['phone'] = new stdClass();
			$checklist['pictures'] = new stdClass();
		}

		foreach ($checklist as $key=>$val) {
			$val->name = JText::_('LNG_'.strtoupper($key));
			$val->status = 0;
		}

		return $checklist;
	}

	/**
	 * Check each field of the item (business/offer/event) relative to the checklist, and
	 * change the status (to 1) if the respective field is already completed.
	 *
	 * @param $item array containing all relevant information about the company/offer/event
	 * @param $type int business->1 offer->2 event->3, default business(1)
	 * @return array checklist array with updated statuses
	 */
	public static function getCompletionProgress($item, $type) {
		$progress = self::getChecklist($type);

		$attributes = self::getAttributeConfiguration($type);
		$appSettings = JBusinessUtil::getApplicationSettings();

		$showAddress = $attributes["street_number"]!=ATTRIBUTE_NOT_SHOW || $attributes["address"]!=ATTRIBUTE_NOT_SHOW ||$attributes["area"]!=ATTRIBUTE_NOT_SHOW
			|| $attributes["country"]!=ATTRIBUTE_NOT_SHOW || $attributes["city"]!=ATTRIBUTE_NOT_SHOW
			|| $attributes["province"]!=ATTRIBUTE_NOT_SHOW || $attributes["region"]!=ATTRIBUTE_NOT_SHOW
			|| $attributes["postal_code"]!=ATTRIBUTE_NOT_SHOW || $attributes["map"]!=ATTRIBUTE_NOT_SHOW;

		if ($type == 1) {
			if (!empty($item->description)) {
				$progress['description']->status = 1;
			}
			if (!empty($item->email)) {
				$progress['email']->status = 1;
			}
			$address = self::getAddressText($item);
			if (!empty($address)) {
				$progress['address']->status = 1;
			}
			if (!empty($item->logoLocation)) {
				$progress['logo']->status = 1;
			}
			if (!empty($item->keywords)) {
				$progress['keywords']->status = 1;
			}
			if (!empty($item->website)) {
				$progress['website']->status = 1;
			}
			if (!empty($item->business_cover_image)) {
				$progress['cover_image']->status = 1;
			}
			if (!empty($item->facebook) || !empty($item->twitter) || !empty($item->googlep) || !empty($item->skype)
				|| !empty($item->linkedin) || !empty($item->youtube) || !empty($item->instagram) || !empty($item->pinterest)) {
				$progress['social_networks']->status = 1;
			}
		} elseif ($type == 2) {
			if (!empty($item->description)) {
				$progress['description']->status = 1;
			}
			if (!empty($item->price)) {
				$progress['price']->status = 1;
			}
			$address = self::getAddressText($item);
			if (!empty($address)) {
				$progress['address']->status = 1;
			}
			if (!empty($item->picture_path)) {
				$progress['pictures']->status = 1;
			}
			if (!self::emptyDate($item->startDate) || !self::emptyDate($item->endDate)) {
				$progress['duration']->status = 1;
			}
		} elseif ($type == 3) {
			if (!empty($item->description)) {
				$progress['description']->status = 1;
			}
			if (!empty($item->contact_email)) {
				$progress['email']->status = 1;
			}
			if (!empty($item->contact_phone)) {
				$progress['phone']->status = 1;
			}
			$address = self::getAddressText($item);
			if (!empty($address)) {
				$progress['address']->status = 1;
			}
			if (!empty($item->picture_path)) {
				$progress['pictures']->status = 1;
			}
			if (!self::emptyDate($item->start_date) || !self::emptyDate($item->end_date)) {
				$progress['duration']->status = 1;
			}
		}

		if (!$showAddress) {
			unset($progress['address']);
		}

		if ($type == 1) {
			$table = JTable::getInstance("Package", "JTable");
			$item->package = $table->getCurrentActivePackage($item->id);
		}

		foreach ($progress as $key=>$val) {
			if ($type == 1) {
				$checkFeature = false;
				if ($key == "logo") {
					$feature = "company_logo";
					$checkFeature = !(isset($item->package->features) && in_array($feature, $item->package->features) || !$appSettings->enable_packages);
				} elseif ($key == "website") {
					$feature = "website_address";
					$checkFeature = !(isset($item->package->features) && in_array($feature, $item->package->features) || !$appSettings->enable_packages);
				} elseif ($key == "description") {
					$checkFeature = !(isset($item->package->features) && in_array($key, $item->package->features) || !$appSettings->enable_packages);
				} elseif ($key == "social_networks") {
					$checkFeature = !(isset($item->package->features) && in_array($key, $item->package->features) || !$appSettings->enable_packages);
				}
				if ($attributes[$key] == ATTRIBUTE_NOT_SHOW || $checkFeature) {
					unset($progress[$key]);
				}
			} else {
				if (isset($attributes[$key]) &&  $attributes[$key] == ATTRIBUTE_NOT_SHOW) {
					unset($progress[$key]);
				}
			}
		}

		return $progress;
	}

	/**
	 * Creates an object containing all necessary fields that will be
	 * mostly used by js functions. These fields will be included in the
	 * JBDUtils object on js.
	 *
	 * @return stdClass
	 */
	public static function addJSSettings() {
		$jsSettings = new stdClass();
		$appSettings = JBusinessUtil::getApplicationSettings();

        if(JFactory::getApplication()->isClient('site') && JFactory::getApplication()->getLanguageFilter()){
            $jsSettings->langaugeCode = self::getCurrentLanguageCode();
        }
		$jsSettings->baseUrl =  JRoute::_('index.php?option=com_jbusinessdirectory');
		$jsSettings->imageRepo = JBusinessUtil::getWebsiteUrl(true) . 'components/com_jbusinessdirectory';
		$jsSettings->imageBaseUrl = (BD_PICTURES_PATH);
		$jsSettings->assetsUrl = (BD_ASSETS_FOLDER_PATH);
		$jsSettings->no_image = $appSettings->no_image;
		$jsSettings->maxFilenameLength = MAX_FILENAME_LENGTH;
		$jsSettings->siteRoot = JBusinessUtil::getWebsiteUrl(true);
		$jsSettings->componentName = JBusinessUtil::getComponentName();
		$jsSettings->timeFormat = $appSettings->time_format;
		$jsSettings->dateFormat = $appSettings->dateFormat;
		$jsSettings->mapType = $appSettings->map_type;
		$jsSettings->mapMarker = $appSettings->map_marker;
		$jsSettings->mapDefaultZoom = (int)$appSettings->map_zoom;
		$jsSettings->enable_attribute_category = $appSettings->enable_attribute_category;
		$jsSettings->enable_packages = $appSettings->enable_packages;
		$jsSettings->isMultilingual = $appSettings->enable_multilingual ? true : false;
		$jsSettings->validateRichTextEditors = false;
		$jsSettings->logo_width = $appSettings->logo_width;
		$jsSettings->logo_height = $appSettings->logo_height;
		$jsSettings->cover_width = $appSettings->cover_width;
		$jsSettings->cover_height = $appSettings->cover_height;
		$jsSettings->gallery_width = $appSettings->gallery_width;
		$jsSettings->gallery_height = $appSettings->gallery_height;
		$jsSettings->enable_crop = $appSettings->enable_crop ? true : false;
		$jsSettings->enable_resolution_check = $appSettings->enable_resolution_check ? true : false;
		$jsSettings->limit_cities_regions = $appSettings->limit_cities_regions ? true : false;
		$jsSettings->enable_map_gdpr = $appSettings->enable_map_gdpr ? true : false;
		$jsSettings->maxAttachments = $appSettings->max_attachments;
		$jsSettings->marker_size = $appSettings->marker_size;
        $jsSettings->month_names = implode(",",JBusinessUtil::getMonthNames());
        $jsSettings->month_names_short = implode(", ",JBusinessUtil::getShortMonthNames());
		$jsSettings->autocomplete_config = $appSettings->autocomplete_config;
		$jsSettings->enable_map_clustering = $appSettings->enable_map_clustering;
		$jsSettings->map_enable_auto_locate = $appSettings->map_enable_auto_locate;
		$jsSettings->projects_style = $appSettings->projects_style;
		$jsSettings->search_filter_items = $appSettings->search_filter_items;
		$jsSettings->event_search_filter_items = $appSettings->event_search_filter_items;
		$jsSettings->offer_search_filter_items = $appSettings->offer_search_filter_items;
		$jsSettings->search_filter_view = $appSettings->search_filter_view;
		$jsSettings->search_type = $appSettings->search_type;
		$jsSettings->event_search_type = $appSettings->event_search_type;
		$jsSettings->offer_search_type = $appSettings->offer_search_type;
		$jsSettings->metric = $appSettings->metric;
		$jsSettings->search_filter_type = $appSettings->search_filter_type;
		$jsSettings->speaker_img_width = $appSettings->speaker_img_width;
		$jsSettings->speaker_img_height = $appSettings->speaker_img_height;
		$jsSettings->location_map_marker = $appSettings->location_map_marker;
		$jsSettings->disable_cropping_types=array(PICTURE_TYPE_CATEGORY_ICON, PICTURE_TYPE_MARKER);
		$jsSettings->enable_ratings = $appSettings->enable_ratings;

		$langTab = JBusinessUtil::getLanguageTag();
		$langTab = str_replace("-", "_", $langTab);
		$jsSettings->langTab = $langTab;

		$jsSettings->defaultLang = JBusinessUtil::getLanguageTag();

		return $jsSettings;
	}

	/**
	 * Get available user groups
	 */
	public static function getUserGroups() {
		//$user = JBusinessUtil::getUser();
		$db = JFactory::getDbo();
		$query = $db->getQuery(true)
				->select('a.id AS value, a.title AS text, COUNT(DISTINCT b.id) AS level')
				->from($db->quoteName('#__usergroups') . ' AS a')
				->join('LEFT', $db->quoteName('#__usergroups') . ' AS b ON a.lft > b.lft AND a.rgt < b.rgt')
				->group('a.id, a.title, a.lft, a.rgt')
				->order('a.lft ASC');
		$db->setQuery($query);
		$options = $db->loadObjectList();

		foreach ($options as &$option) {
			$option->name = str_repeat('- ', $option->level) . $option->text;
		}

		return $options;
	}

	/**
	 *  Get all users on system
	 */
	public static function getAllUsers() {
		$db = JFactory::getDbo();
		$query = $db->getQuery(true)
			->select('a.id AS value, a.name AS text, a.username AS username')
			->from($db->quoteName('#__users') . ' AS a')
			->order('a.id ASC');
		$db->setQuery($query);
		$options = $db->loadObjectList();

		foreach ($options as &$option) {
			$option->name = $option->text. "-" . $option->username;
		}

		return $options;
	}

	/**
	 * Method to retrieve the ID of an extension based by it's type and name
	 *
	 * @param $type string type of the extension
	 * @param $name string name of the extension
	 * @return mixed
	 */
	public static function getExtensionID($type, $name) {
		$db = JFactory::getDbo();

		$query = "select ext.extension_id 
                  from #__extensions as ext
                  where ext.type='$type' and ext.element = '$name'
                  ";

		$db->setQuery($query);
		$result = $db->loadObject();

		return $result->extension_id;
	}

	/**
	 *  Return the id of the country based on hic code
	 * @param $countryCode
	 * @return mixed
	 */
	public static function getCountryIDByCode($countryCode) {
		$db = JFactory::getDbo();

		$query = "select co.id 
                  from #__jbusinessdirectory_countries as co
                  where co.country_code = '$countryCode'
                  ";

		$db->setQuery($query);
		$result = $db->loadObject();

		return $result->id;
	}

	/**
	 * This function get the content as a string and removes all rel attributes on anchor links if there is any
	 *
	 * @param $string string content that will be analyzed and where the rel attribute will be removed
	 * @return mixed string content with rel attributes removed
	 */
	public static function removeRelAttribute($string) {
		$string = str_replace("rel=","",$string);
		return $string;
	}

	/**
	 * Method that groups all attributes together in an array based on the group name.
	 * The indexes of the final 2-dimensional array will correspond to the group, and all
	 * attributes belonging to that group will be inside an array in that particular index.
	 *
	 * An extra index called ungrouped is created for the attributes with no group.
	 *
	 * @param $attributes array containing all attributes with their relevant fields
	 *
	 * @return array
	 *
	 * @since 4.9.0
	 */
	public static function arrangeAttributesByGroup($attributes) {
		$groupedAttr = array();
		$groupedAttr['ungrouped'] = array();
		foreach ($attributes as $attribute) {
			if (!empty($attribute->group)) {
				if (!isset($groupedAttr[$attribute->group])) {
					$groupedAttr[$attribute->group] = array();
				}

				$groupedAttr[$attribute->group][] = $attribute;
			} else {
				$groupedAttr['ungrouped'][] = $attribute;
			}
		}

		return $groupedAttr;
	}
	
	/**
	 * Filter payment methods based on package type.
	 * If package is of type recurring and there is a recurring payment method available, only that method will be visible
	 *
	 * @param unknown $order
	 * @param unknown $paymentMethods
	 */
	public static function filterPaymentMethods($order, $paymentMethods) {
		$result = array();
		
		if (empty($order)) {
			return $paymentMethods;
		}
		
		if ($order->package->expiration_type == 3 || $order->package->expiration_type == 4) {
			foreach ($paymentMethods as $paymentMethod) {
				if (isset($paymentMethod->recurring) && $paymentMethod->recurring) {
					$result[] = $paymentMethod;
				}
			}
		}else{
			foreach ($paymentMethods as $paymentMethod) {
				if (!(isset($paymentMethod->recurring) && $paymentMethod->recurring)) {
					$result[] = $paymentMethod;
				}
			}
		}
		
		if (!empty($result)) {
			return $result;
		}
		
		return $paymentMethods;
	}

	/**
	 * Loads the appropriate scripts depending on the selected map type on
	 * general settings or the one provided as a parameter.
	 * Will return also the value of the respective API key.
	 *
	 * @param null $mapType int type of the map
	 *
	 * @param bool $asyncDefer
	 *
	 * @return string
	 *
	 * @since 4.9.5
	 */
	public static function loadMapScripts($mapType = null, $asyncDefer = false) {
		$key         = "";
		$lang        = JBusinessUtil::getLanguageTag();
		$appSettings = JBusinessUtil::getApplicationSettings();

		if (empty($mapType)) {
			$mapType = $appSettings->map_type;
		}

		if ($mapType == MAP_TYPE_GOOGLE) {
			if (!empty($appSettings->google_map_key)) {
				$key = "&key=" . $appSettings->google_map_key;
			}
			JHtml::_('script', "https://maps.googleapis.com/maps/api/js?language=" . $lang . $key . "&libraries=geometry&libraries=places");

			if ($appSettings->enable_map_clustering) {
			    JHtml::_('script', "https://unpkg.com/@google/markerclustererplus@4.0.1/dist/markerclustererplus.min.js");
            }

		} elseif ($mapType == MAP_TYPE_BING) {
			if (!empty($appSettings->bing_map_key)) {
				$key = $appSettings->bing_map_key;
			}

			JHtml::_('script', "https://www.bing.com/api/maps/mapcontrol?key=$key");
		} elseif ($mapType == MAP_TYPE_OSM) {
			JBusinessUtil::loadJQueryUI();			

			JBusinessUtil::enqueueStyle('libraries/leaflet/leaflet.css');
			JBusinessUtil::enqueueStyle('libraries/leaflet/leaflet-search.css');
			JBusinessUtil::enqueueScript('libraries/leaflet/leaflet.js');
			JBusinessUtil::enqueueScript('libraries/leaflet/leaflet-search.js');

			JBusinessUtil::enqueueStyle('libraries/leaflet/leaflet.fullscreen.css');
			JBusinessUtil::enqueueScript('libraries/leaflet/leaflet.fullscreen.min.js');

			if ($appSettings->enable_map_clustering) {
				JBusinessUtil::enqueueScript('libraries/leaflet/leaflet.markercluster.js');
				JBusinessUtil::enqueueStyle('libraries/leaflet/MarkerCluster.css');
				JBusinessUtil::enqueueStyle('libraries/leaflet/MarkerCluster.Default.css');
			}
		}

		return $key;
	}

	/**
	 * Gets a static map image of the provided position (lat, long).
	 *
	 * @param float  $lat latitude of the position
	 * @param float  $long longitude of the position
	 * @param string $class css class of the image
	 * @param int    $width of the map
	 * @param int    $height of the map
	 * @param int    $zoom
	 * @param int    $mapType defaults to google map if not specified
	 *
	 * @return string
	 *
	 * @since 4.9.5
	 */
	public static function getStaticMap($lat, $long, $class = "company map", $width = 400, $height = 300, $zoom = 13, $mapType = null) {
		$db = JFactory::getDbo();
		$appSettings = JBusinessUtil::getApplicationSettings();

		$html = '';
		$src  = '';

		$lat   = $db->escape($lat);
		$long  = $db->escape($long);

		if (empty($mapType)) {
			$mapType = $appSettings->map_type;
		}

		if ($mapType == MAP_TYPE_GOOGLE) {
			$key = "&key=".$appSettings->google_map_key;

			$src = "https://maps.googleapis.com/maps/api/staticmap?center=";
			$src .= $lat.",".$long;
			$src .= "&zoom=".$zoom."&size=".$width."x".$height."&markers=color:blue|";
			$src .= $lat.",".$long;
			$src .= $key;
			$src .= "&sensor=false";
		} elseif ($mapType == MAP_TYPE_BING) {
			$key = "&key=".$appSettings->bing_map_key;

			$src = "https://dev.virtualearth.net/REST/v1/Imagery/Map/Road/";
			$src .= $lat.",".$long;
			$src .="/".$zoom;
			$src .= "?mapSize=".$width.",".$height;
			$src .= "&pp=".$lat.",".$long;
			$src .= $key;
		} elseif ($mapType == MAP_TYPE_OSM) {
			$src = JBusinessUtil::getWebsiteUrl(true).'components/'.JBusinessUtil::getComponentName().'/libraries/staticmaplite/staticmap.php?';
			$src .= "center=".$lat.",".$long;
			$src .= "&zoom=".$zoom;
			$src .= "&size=".$width."x".$height;
			$src .= "&markers=".$lat.",".$long;
		}

		$html .= "<img alt='".$class."' ";
		$html .= "src='".$src."'";
		$html .= ">";

		return $html;
	}

	/**
	 * Loads all base scripts needed for all JBD
	 *
	 * @since 5.3.1
	 */
	public static function loadBaseScripts() {
        //JBusinessUtil::enqueueScript('libraries/react/development/react.development.js');
        //JBusinessUtil::enqueueScript('libraries/react/development/react-dom.development.js');
		JBusinessUtil::enqueueScript('libraries/react/production/react.production.min.js');
        JBusinessUtil::enqueueScript('libraries/react/production/react-dom.production.min.js');
        JBusinessUtil::enqueueScript('libraries/babel/babel.min.js');
		JBusinessUtil::enqueueScript('js/jbd-app.js');
	}

	/**
	 * get yelp data
	 * @param $id int listing id on yelp
	 * @param bool $getReviews get Reviews of listing or not
	 * @return mixed
	 */
	public static function getYelpData($id, $getReviews = false) {
		$access_token = 'V0RYaofP72UIt0j7ohSOU1OX2V_hfKPwRdk7WPrWCO-XcZPMjmhe-rzGyBDhrYki_izUfrBsCx8qyydyRcz1Sy7gDSU6GbZCxj-IYre_O6-Mqzsj6qG4ydNKGUVDWHYx';
		$url = 'https://api.yelp.com/v3/businesses/'.$id;

		if ($getReviews) {
			$url .= '/reviews';
		}

		//Initialize cURL.
		$ch = curl_init();

		//Set the URL that you want to GET by using the CURLOPT_URL option.
		curl_setopt($ch, CURLOPT_URL, $url);

		//Set CURLOPT_RETURNTRANSFER so that the content is returned as a variable.
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		curl_setopt(
			$ch,
			CURLOPT_HTTPHEADER,
			array(
				'token_type: Bearer',
				'Authorization: Bearer '.$access_token,
			)
		);

		//Set CURLOPT_FOLLOWLOCATION to true to follow redirects.
		curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);

		//Execute the request.
		$data = curl_exec($ch);

		//Close the cURL handle.
		curl_close($ch);
		//dump(json_decode($data));exit;
		return json_decode($data);
	}

	/**
	 * Get more search filter options
	 *
	 * @return array
	 */
	public static function getMoreSearchFilterOptions() {
		$options = array();

		$option = new stdClass();
		$option->value = 'with_address';
		$option->text = JTEXT::_("LNG_WITH_ADDRESS");
		$options[] = $option;

		$option = new stdClass();
		$option->value = 'with_contact';
		$option->text = JTEXT::_("LNG_WITH_CONTACT");
		$options[] = $option;

		$option = new stdClass();
		$option->value = 'with_phone';
		$option->text = JTEXT::_("LNG_WITH_PHONE");
		$options[] = $option;

		$option = new stdClass();
		$option->value = 'with_email';
		$option->text = JTEXT::_("LNG_WITH_EMAIL");
		$options[] = $option;

		$option = new stdClass();
		$option->value = 'with_social_networks';
		$option->text = JTEXT::_("LNG_WITH_SOCIAL_NETWORKS");
		$options[] = $option;

		$option = new stdClass();
		$option->value = 'with_website';
		$option->text = JTEXT::_("LNG_WITH_WEBSITE");
		$options[] = $option;

		$option = new stdClass();
		$option->value = 'with_images';
		$option->text = JTEXT::_("LNG_WITH_IMAGES");
		$options[] = $option;

		$option = new stdClass();
		$option->value = 'with_videos';
		$option->text = JTEXT::_("LNG_WITH_VIDEOS");
		$options[] = $option;

		$option = new stdClass();
		$option->value = 'with_attached_file';
		$option->text = JTEXT::_("LNG_WITH_ATTACHED_FILE");
		$options[] = $option;

		$option = new stdClass();
		$option->value = 'with_description';
		$option->text = JTEXT::_("LNG_WITH_DESCRIPTION");
		$options[] = $option;

		$option = new stdClass();
		$option->value = 'with_products_offers';
		$option->text = JTEXT::_("LNG_WITH_PRODUCTS_OFFERS");
		$options[] = $option;

		$option = new stdClass();
		$option->value = 'with_events';
		$option->text = JTEXT::_("LNG_WITH_EVENTS");
		$options[] = $option;

        $option = new stdClass();
        $option->value = 'with_appointments';
        $option->text = JTEXT::_("LNG_WITH_APPOINTMENTS");
        $options[] = $option;

		return $options;
	}

	/**
	 * Returns the URL of the upload controller along with the specified
	 * controller function
	 *
	 * @param string $task name of the controller function
	 *
	 * @return string
	 */
	public static function getUploadUrl($task = 'upload') {
		return JBusinessUtil::getWebsiteUrl(true).'index.php?option=com_jbusinessdirectory&task=upload.'.$task;
	}
	
	public static function showMandatory($isMandatory) {
		$result = "";
		if ($isMandatory == ATTRIBUTE_MANDATORY) {
			$result = '<span class="star" aria-hidden="true">&nbsp;*</span>';
		}
		return $result;
	}

	/**
	 * Function that converts one currency to another by using the service provided by
	 * free.currencyconverterapi.com
	 *
	 * @param      $amount       float the amount to be converted
	 * @param      $fromCurrency int ID of the current currency
	 * @param null $toCurrency   int ID of the currency we want to convert to, defaults to app settings currency
	 *
	 * @return float|int
	 *
	 * @since 5.0.1
	 */
	public static function convertCurrency($amount, $fromCurrency, $toCurrency = null) {
		$appSettings = JBusinessUtil::getApplicationSettings();

		if (empty($appSettings->currency_converter_api)) {
			return $amount;
		}

		if (empty($toCurrency)) {
			$toCurrency = $appSettings->currency_id;
		}

		JTable::addIncludePath(JPATH_ROOT . '/administrator/components/com_jbusinessdirectory/tables');
		$currencyTable = JTable::getInstance("Currency", "JTable");
		$fromCurrency  = $currencyTable->getCurrencyById($fromCurrency)->currency_name;
		$toCurrency    = $currencyTable->getCurrencyById($toCurrency)->currency_name;

		if (function_exists('curl_init')) {
			$url = "https://free.currencyconverterapi.com/api/v6/convert?apiKey=" . $appSettings->currency_converter_api;
			$url .= "&q=" . $fromCurrency . "_" . $toCurrency;

			$ch      = curl_init();
			$timeout = 0;
			curl_setopt($ch, CURLOPT_URL, $url);
			curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
			curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1");
			curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
			curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
			$rawdata = curl_exec($ch);

			curl_close($ch);

			$data = json_decode($rawdata);
			if (empty($data) || $data->query->count == 0) {
				return $amount;
			} else {
				$field = $fromCurrency . "_" . $toCurrency;
				return $amount * $data->results->$field->val;
			}
		} else {
			return $amount;
		}
	}

	/**
	 * Checks if the provided JBD App is installed or not.
	 *
	 * @param $app int type of the JBD app
	 *
	 * @return bool
	 *
	 * @since 5.0.2
	 */
	public static function isAppInstalled($app) {
		$path = '';
		switch ($app) {
			case JBD_APP_APPOINTMENTS:
				$path = JPATH_ADMINISTRATOR . '/components/com_jbusinessdirectory/controllers/companyservice.php';
				break;
			case JBD_APP_SELL_OFFERS:
				$path = JPATH_ADMINISTRATOR . '/components/com_jbusinessdirectory/controllers/offerorder.php';
				break;
			case JBD_APP_EVENT_BOOKINGS:
				$path = JPATH_ADMINISTRATOR . '/components/com_jbusinessdirectory/controllers/eventreservation.php';
				break;
			case JBD_APP_EVENT_APPOINTMENTS:
				$path = JPATH_ADMINISTRATOR . '/components/com_jbusinessdirectory/controllers/eventappointment.php';
				break;
			case JBD_APP_CAMPAIGNS:
				$path = JPATH_ADMINISTRATOR . '/components/com_jbusinessdirectory/controllers/campaigns.php';
				break;
			case JBD_APP_QUOTE_REQUESTS:
				$path = JPATH_ADMINISTRATOR . '/components/com_jbusinessdirectory/controllers/requestquotes.php';
				break;
			case JBD_APP_STRIPE:
				$path = JPATH_SITE . '/components/com_jbusinessdirectory/classes/payment/processors/StripeProcessor.php';
				break;
			case JBD_APP_STRIPE_SUBSCRIPTIONS:
				$path = JPATH_SITE . '/components/com_jbusinessdirectory/classes/payment/processors/StripeSubscriptions.php';
				break;
			case JBD_APP_PAYPAL_SUBSCRIPTIONS:
				$path = JPATH_SITE . '/components/com_jbusinessdirectory/classes/payment/processors/PaypalSubscriptions.php';
				break;
			case JBD_APP_PAYFAST_SUBSCRIPTIONS:
				$path = JPATH_SITE . '/components/com_jbusinessdirectory/classes/payment/processors/PayfastSubscriptions.php';
				break;
			case JBD_APP_AUTHORIZE:
				$path = JPATH_SITE . '/components/com_jbusinessdirectory/classes/payment/processors/Authorize.php';
				break;
			case JBD_APP_AUTHORIZE_SUBSCRIPTIONS:
				$path = JPATH_SITE . '/components/com_jbusinessdirectory/classes/payment/processors/AuthorizeSubscriptions.php';
				break;
            case JBD_APP_MERCADO_PAGO:
                $path = JPATH_SITE . '/components/com_jbusinessdirectory/classes/payment/processors/MercadoPagoProcessor.php';
				break;
			case JBD_APP_ELASTIC_SEARCH:
				$path = JPATH_SITE . '/components/com_jbusinessdirectory/classes/elasticsearch/JBusinessElasticHelper.php';
				break;
			case JBD_APP_TRIPS:
				$path = JPATH_SITE . '/components/com_jbusinessdirectory/controllers/trip.php';
				break;
			default:
				$path = '';
		}

		if (empty($path)) {
			return false;
		}

		return file_exists($path);
	}

	/**
	 * Increase the GROUP_CONTACT lenght to 10000 characters
	 *
	 * @return mixed
	 */
	public static function setGroupConcatLenght() {
		$instance = JBusinessUtil::getInstance();
		
		if (isset($instance->groupConcatLenghtSet)) {
			return $instance->groupConcatLenghtSet;
		}
		
		$db =JFactory::getDBO();
		
		$db->setQuery("SET SESSION group_concat_max_len = 10000");
		$instance->groupConcatLenghtSet = $db->execute();
		
		return $instance->groupConcatLenghtSet;
	}

	/**
	 * SET SQL_BIG_SELECTS=1
	 * @return mixed
	 */
	public static function setBigSqlSelects() {
		$instance = JBusinessUtil::getInstance();
		
		if (isset($instance->bigSqlSelects)) {
			return $instance->bigSqlSelects;
		}
		
		$db =JFactory::getDBO();
		
		$db->setQuery("SET SQL_BIG_SELECTS=1");
		$instance->bigSqlSelects = $db->execute();
		
		return $instance->bigSqlSelects;
	}

	/**
	 * Get announcements action types and default options
	 *
	 * @return array
	 */
	public static function getAnnouncementActions() {
		$options = array();

		$option = new stdClass();
		$option->id = '1';
		$option->name = JTEXT::_("LNG_ANNOUNCEMENTS");
		$option->title = JTEXT::_("LNG_ANNOUNCEMENT_ACTION_TITLE");
		$option->description = JTEXT::_("LNG_ANNOUNCEMENT_ACTION_DESCRIPTION");
		$option->icon = 'icon bullhorn';
		$option->button_text = JTEXT::_("LNG_ANNOUNCEMENT_ACTION_BUTTON_TEXT");
		$option->button_link = JTEXT::_("LNG_ANNOUNCEMENT_ACTION_BUTTON_LINK");
		$options[$option->id] = $option;

		$option = new stdClass();
		$option->id = '2';
		$option->name = JTEXT::_("LNG_CONTACT_US");
		$option->title = JTEXT::_("LNG_CONTACT_US_ACTION_TITLE");
		$option->description = JTEXT::_("LNG_CONTACT_US_ACTION_DESCRIPTION");
		$option->icon = 'la la-envelope-o';
		$option->button_text = JTEXT::_("LNG_CONTACT_US_ACTION_BUTTON_TEXT");
		$option->button_link = JTEXT::_("LNG_CONTACT_US_ACTION_BUTTON_LINK");
		$options[$option->id] = $option;

		$option = new stdClass();
		$option->id = '3';
		$option->name = JTEXT::_("LNG_BOOK_NOW");
		$option->title = JTEXT::_("LNG_BOOK_NOW_ACTION_TITLE");
		$option->description = JTEXT::_("LNG_BOOK_NOW_ACTION_DESCRIPTION");
		$option->icon = 'la la-adjust';
		$option->button_text = JTEXT::_("LNG_BOOK_NOW_ACTION_BUTTON_TEXT");
		$option->button_link = JTEXT::_("LNG_BOOK_NOW_ACTION_BUTTON_LINK");
		$options[$option->id] = $option;

		$option = new stdClass();
		$option->id = '4';
		$option->name = JTEXT::_("LNG_BUY_TICKETS");
		$option->title = JTEXT::_("LNG_BUY_TICKETS_ACTION_TITLE");
		$option->description = JTEXT::_("LNG_BUY_TICKETS_ACTION_DESCRIPTION");
		$option->icon = 'la la-cart-plus';
		$option->button_text = JTEXT::_("LNG_BUY_TICKETS_ACTION_BUTTON_TEXT");
		$option->button_link = JTEXT::_("LNG_BUY_TICKETS_ACTION_BUTTON_LINK");
		$options[$option->id] = $option;

		$option = new stdClass();
		$option->id = '5';
		$option->name = JTEXT::_("LNG_GET_OFFER");
		$option->title = JTEXT::_("LNG_GET_OFFER_ACTION_TITLE");
		$option->description = JTEXT::_("LNG_GET_OFFER_ACTION_DESCRIPTION");
		$option->icon = 'la la-envelope-o';
		$option->button_text = JTEXT::_("LNG_GET_OFFER_ACTION_BUTTON_TEXT");
		$option->button_link = JTEXT::_("LNG_GET_OFFER_ACTION_BUTTON_LINK");
		$options[$option->id] = $option;

		$option = new stdClass();
		$option->id = '6';
		$option->name = JTEXT::_("LNG_GET_QUOTE");
		$option->title = JTEXT::_("LNG_GET_QUOTE_ACTION_TITLE");
		$option->description = JTEXT::_("LNG_GET_QUOTE_ACTION_DESCRIPTION");
		$option->icon = 'icon bullhorn';
		$option->button_text = JTEXT::_("LNG_GET_QUOTE_ACTION_BUTTON_TEXT");
		$option->button_link = JTEXT::_("LNG_GET_QUOTE_ACTION_BUTTON_LINK");
		$options[$option->id] = $option;

		$option = new stdClass();
		$option->id = '7';
		$option->name = JTEXT::_("LNG_JOIN_NOW");
		$option->title = JTEXT::_("LNG_JOIN_NOW_ACTION_TITLE");
		$option->description = JTEXT::_("LNG_JOIN_NOW_ACTION_DESCRIPTION");
		$option->icon = 'la la-adjust';
		$option->button_text = JTEXT::_("LNG_JOIN_NOW_ACTION_BUTTON_TEXT");
		$option->button_link = JTEXT::_("LNG_JOIN_NOW_ACTION_BUTTON_LINK");
		$options[$option->id] = $option;

		$option = new stdClass();
		$option->id = '8';
		$option->name = JTEXT::_("LNG_SCHEDULE_NOW");
		$option->title = JTEXT::_("LNG_SCHEDULE_NOW_ACTION_TITLE");
		$option->description = JTEXT::_("LNG_SCHEDULE_NOW_ACTION_DESCRIPTION");
		$option->icon = 'la la-calendar';
		$option->button_text = JTEXT::_("LNG_SCHEDULE_NOW_ACTION_BUTTON_TEXT");
		$option->button_link = JTEXT::_("LNG_SCHEDULE_NOW_ACTION_BUTTON_LINK");
		$options[$option->id] = $option;

		return $options;
	}

	/**
	 * Get Website URL
	 * @return string
	 */
	public static function getWebsiteURL($root = false) {
		$uri = JURI::getInstance();
		$base = $uri->getScheme()."://".$uri->getHost();

		if($root) {
			$baseUrl = $base . JURI::root(true)."/";
		} else {
			$baseUrl = $base;
		}

		return $baseUrl;
	}

	/**
	 * Get responsive content place holders
	 *
	 * @return array
	 */
	public static function getPlaceholders() {
		$placeholders = array(
			PLACEHOLDER_COMPANY_NAME => JText::_("LNG_PLACEHOLDER_COMPANY_NAME"),
			PLACEHOLDER_ADDRESS => JText::_("LNG_ADDRESS"),
			PLACEHOLDER_EMAIL => JText::_("LNG_EMAIL")
		);

		return $placeholders;
	}

	/**
	 * Process responsible content
	 * @param $company object company object
	 * @param $content string content to process
	 * @return string|string[]
	 */
	public static function processResponsibleCotent($company, $content) {
		$content = str_replace(PLACEHOLDER_COMPANY_NAME, $company->name, $content);
		$content = str_replace(PLACEHOLDER_ADDRESS, self::getAddressText($company), $content);
		$content = str_replace(PLACEHOLDER_EMAIL, $company->email, $content);
		$content = str_replace(PLACEHOLDER_PHONE, $company->phone, $content);

		return $content;
	}

	/**
	 * Generate a message for pages with no items with a new item button
	 *
	 * @param $singleItemText string text for single item
	 * @param $multipleItemsText string text for multiple items
	 * @param $actionUrl string url for creating new item
	 * @return false|string
	 */
	public static function getNewItemMessageBlock($singleItemText, $multipleItemsText, $actionUrl) {
		$title = JText::sprintf('LNG_MESSAGE_CREATE_NEW_TITLE', strtolower($multipleItemsText));
		$text=JText::sprintf('LNG_MESSAGE_CREATE_NEW_TEXT', strtolower($singleItemText));
		$btnText = JText::sprintf('LNG_MESSAGE_BTN_CREATE_NEW', $singleItemText);
		ob_start(); ?>
        <div class="jbd-message-container">
        	<div>
        		<img class="message-image" alt="Create new"
        			src="data:image/png;base64, ">
        		<h2 class="message-header"><?php echo $title ?></h2>
        		<p class="messge-text">
        			<?php echo $text ?>
        		</p>
        		<p>
        			<a href="<?php echo $actionUrl?>" class="btn btn-success m-2 px-5 py-2" type="button">
        				<i class="la la-plus"></i> <?php echo ucwords($btnText) ?>
        			</a>
        		</p>
        	</div>
        </div>
        <?php
		
		// Done with the requested template; get the buffer and
		// clear it.
		$messageContent = ob_get_contents();
		ob_end_clean();
		
		return $messageContent;
	}

	/**
	 * Generate a message for pages with no items
	 *
	 * @param $singleItemText string text for single item
	 * @param $multipleItemsText string text for multiple items
	 * @return false|string
	 */
	public static function getNoItemMessageBlock($singleItemText, $multipleItemsText) {
		$title = JText::sprintf('LNG_MESSAGE_NO_ITEMS_TITLE', mb_strtolower($multipleItemsText));
		$text=JText::sprintf('LNG_MESSAGE_NO_ITEMS_TEXT', mb_strtolower($singleItemText));
		ob_start(); ?>
        <div class="jbd-message-container">
        	<div>	
        		<img class="message-image" alt="Create new"
        			src="data:image/png;base64, ">
        		<h3 class="message-header"><?php echo $title ?></h3>
        		<p class="messge-text">
        			<?php echo $text ?>
        		</p>
        	</div>
        </div>
        <?php
		
		// Done with the requested template; get the buffer and
		// clear it.
		$messageContent = ob_get_contents();
		ob_end_clean();
		
		return $messageContent;
	}

	/**
	 * Returns the HTMl for the Map GDPR Modal
	 *
	 * @return string HTML of the modal
	 *
	 * @since 5.2.0
	 */
	public static function getMapGDPRModal() {
		return '<div class="jmodal-sm" id="map-gdpr-modal" style="display:none;text-align:center;">
                <div class="jmodal-header">
                    <h3>'.JText::_("LNG_MAP_GDPR_TITLE").'</h3>
                    <hr/>
                </div>
                <div class="jmodal-body">
                    <div class="d-flex justify-content-between">
                        <img class="map-gdpr-img" />
                        <p>'.JText::_("LNG_MAP_GDPR_TEXT").'</p>
                    </div>
                    <br/>
                </div>
                <div class="jmodal-footer">
                    <div class="btn-group" role="group" aria-label="">
                        <button type="button" id="gdpr-deny-btn" class="jmodal-btn btn btn-secondary">'.JText::_("LNG_DENY").'</button>
                        <button type="button" id="gdpr-accept-btn" class="jmodal-btn btn btn-success">'.JText::_("LNG_ACCEPT").'</button>
                    </div>
                </div>
            </div>';
	}

	/**
	 * Retrieves companies based on search string
	 *
	 * @param      $str string search string
	 * @param null $userId int ID of the user
	 *
	 * @return array
	 *
	 * @since 5.2.0
	 */
	public static function getCompaniesByString($str, $userId = null) {
		JTable::addIncludePath(JPATH_ROOT . '/administrator/components/com_jbusinessdirectory/tables');
		$companyTable = JTable::getInstance("Company", "JTable");

		$company = $companyTable->getCompaniesByString($str, $userId);

		$result = array();
		foreach ($company as $item) {
			$result[] = $item;
		}

		return $result;
	}

	/**
	 * Retrieves Events based on search string
	 *
	 * @param      $str string search string
	 * @param null $userId int ID of the user
	 *
	 * @return array
	 *
	 * @since 5.2.0
	 */
	public static function getEventsByString($str, $userId = null) {
		JTable::addIncludePath(JPATH_ROOT . '/administrator/components/com_jbusinessdirectory/tables');
		$table = JTable::getInstance("Event", "JTable");

		$items = $table->getEventsByString($str, $userId);

		$result = array();
		foreach ($items as $item) {
			$result[] = $item;
		}

		return $result;
	}

	/**
	 * Retrieves Offers based on search string
	 *
	 * @param      $str string search string
	 * @param null $userId int ID of the user
	 *
	 * @return array
	 *
	 * @since 5.2.0
	 */
	public static function getOffersByString($str, $userId = null) {
		JTable::addIncludePath(JPATH_ROOT . '/administrator/components/com_jbusinessdirectory/tables');
		$table = JTable::getInstance("Offer", "JTable");

		$items = $table->getOffersByString($str, $userId);

		$result = array();
		foreach ($items as $item) {
			$result[] = $item;
		}

		return $result;
	}

	/**
	 * Retrieves Offers based on search string
	 *
	 * @param      $str string search string
	 * @param null $userId int ID of the user
	 *
	 * @return array
	 *
	 * @since 5.2.0
	 */
	public static function getSessionLocationByString($str, $userId = null) {
		JTable::addIncludePath(JPATH_ROOT . '/administrator/components/com_jbusinessdirectory/tables');
		$table = JTable::getInstance("SessionLocation", "JTable");

		$items = $table->getSessionLocationByString($str, $userId);

		$result = array();
		foreach ($items as $item) {
			$result[] = $item;
		}

		return $result;
	}


    /**
     * Get companies by user id
     *
     * @return array
     */
    public static function getCompaniesByUserId($userId = null, $idsOnly = false) {
        if (empty($userId)) {
            $user = self::getUser();
            $userId = $user->id;
        }

        JTable::addIncludePath(JPATH_ROOT . '/administrator/components/com_jbusinessdirectory/tables');
        $companyTable = JTable::getInstance("Company", "JTable");

        $companies = $companyTable->getCompaniesByUserId($userId);

        if ($idsOnly) {
            $result = array();
            foreach ($companies as $company) {
                $result[] = $company->id;
            }
            $companies = $result;
        }

        return $companies;
    }

	/**
	 * Get user events
	 * @param $userId int user id by default is null
	 * @return array
	 */
	public static function getUserEvents($userId = null) {
		if (empty($userId)) {
			$user = self::getUser();
			$userId = $user->id;
		}

		JTable::addIncludePath(JPATH_ROOT . '/administrator/components/com_jbusinessdirectory/tables');
		$table = JTable::getInstance("Event", "JTable");

		$items =  $table->getUserEvents($userId);
		$result = array();
		foreach ($items as $item) {
			$result[] = $item->id;
		}
		return $result;
	}


	/**
	 * Subscract $subsctract array from source array
	 * 
	 */
	public static function substractArrays($source, $substract){
		$result = array();
		foreach($source as $src){
			$found = false;
			foreach($substract as $sub){
				if($src->id == $sub->id){
					$found = true;
					break;
				}
			}
			if(!$found){
				$result[] = $src;
			}
		}

		return $result;
	}

	/**
	 * Generate request summary for quote requests
	 *
	 * @param $summary object summary details
	 * @return string
	 */
	public static function generateRequestSummary($summary) {
		$questionAnsers = json_decode($summary);
		$text = '';
		foreach ($questionAnsers as $option) {
			$answers = explode('#', $option->answer);
			unset($answers[0]);

			$text .= "<p style='margin: unset'><strong>" . $option->question . "</strong>:</p>";
			$count = 1;
			foreach ($answers as $answer) {
				$text .= "<p style='margin-bottom:unset'>-" . $answer . " </p>";
			}
		}
		return $text;
	}

	/**
	 * Loads the upload script along with the required translations. Will also render the HTML needed by the JS on screen.
	 *
	 * @since 5.3.0
	 *
	 * @param bool $includeAttachments      boolean if true, will include the HTML for attachments
	 * @param bool $includeDropzonePictures boolean if true, will include the HTML for the dropzone images list
	 * @param bool $includeCropper  boolean if true, will include the cropper modal HTML
	 */
	public static function loadUploadScript($includeAttachments = false, $includeDropzonePictures = false, $includeCropper = true, $extraPictures = false) {
		JBusinessUtil::enqueueScript('libraries/jquery/jquery.upload.js');
		
		JText::script('LNG_IMAGE_SIZE_WARNING');
		JText::script('LNG_FILE_ALLREADY_ADDED');
		JText::script('LNG_ERROR_ADDING_FILE');
		JText::script('LNG_ERROR_RESIZING_FILE');
		JText::script('LNG_ERROR_REMOVING_FILE');
		JText::script('LNG_FILE_DOESNT_EXIST');
		JText::script('LNG_FILENAME_TOO_LONG');
		JText::script('LNG_MAX_ATTACHMENTS_ALLOWED');
		JText::script('LNG_CONFIRM_DELETE_ATTACHMENT');
		JText::script('LNG_CONFIRM_DELETE_PICTURE');

		$attachmentTemplate = '
        <div id="attachment-item-template" style="display:none;">
                <li class="jbd-item" id="jbd-item-{attachment_id}">
                    <div class="jupload-files">
                        <div class="jupload-files-img">
                            <i class="la la-file"></i>
                        </div>
                        <div class="jupload-files-info">
                            <div class="jupload-filename">
                                <p>{attachment_path}</p>
                                <input id="jupload-filename-{attachment_id}" type="text"
                                       name="attachment_name[]" value="{attachment_name}">
                            </div>
                            <div class="jupload-actions jbd-item-actions">
                                <label for="jupload-filename-{attachment_id}">
                                    <i class="la la-pencil"></i>
                                </label>
            
                                <input type="hidden" name="attachment_status[]" id="attachment_status_{attachment_id}" value="{attachment_status}" />
                                <input type=\'hidden\' name=\'attachment_path[]\' id=\'attachment_path_{attachment_id}\' value=\'{attachment_full_path}\' />
                            </div>
                        </div>
                    </div>
                </li>
            </div>';

		$pictureTemplate = '
            <div id="picture-item-template" style="display:none;">
                <li class="jbd-item" id="jbd-item-{picture_id}">
                    <div class="jupload-files">
                        <div class="jupload-files-img">
                            {picture_link}
                        </div>
                        <div class="jupload-files-info">
                            <div class="jupload-filename">
                                <p>{picture_path}</p>
                                <input id="jupload-filename-{picture_id}" type="text"
                                       name="picture_title[]" value="{picture_title}" placeholder="'.JText::_("LNG_TITLE").'">
                                <input id="jupload-filename-{picture_id}" type="text"
                                       name="picture_info[]" value="{picture_info}" placeholder="'.JText::_("LNG_DESCRIPTION").'">
                            </div>
                            <div class="jupload-actions jbd-item-actions">
                                <label for="jupload-filename-{picture_id}">
                                    <i class="la la-pencil"></i>
                                </label>
            
                                <input type="hidden" name="picture_enable[]" id="picture_enable_{picture_id}" value="{picture_enable}" />
                                <input type=\'hidden\' name=\'picture_path[]\' id=\'picture_path_{picture_id}\' value=\'{picture_full_path}\' />
                            </div>
                        </div>
                    </div>
                </li>
            </div>';

			$extraPictureTemplate = '
            <div id="extra-picture-item-template" style="display:none;">
                <li class="jbd-item" id="jbd-item-{image_id}">
                    <div class="jupload-files">
                        <div class="jupload-files-img">
                            {image_link}
                        </div>
                        <div class="jupload-files-info">
                            <div class="jupload-filename">
                                <p>{image_path}</p>
                                <input id="jupload-filename-{image_id}" type="text"
                                       name="image_title[]" value="{image_title}" placeholder="'.JText::_("LNG_TITLE").'">
                                <input id="jupload-filename-{image_id}" type="text"
                                       name="image_info[]" value="{image_info}" placeholder="'.JText::_("LNG_DESCRIPTION").'">
                            </div>
                            <div class="jupload-actions jbd-item-actions">
                                <label for="jupload-filename-{image_id}">
                                    <i class="la la-pencil"></i>
                                </label>
            
                                <input type="hidden" name="image_enable[]" id="image_enable_{image_id}" value="{image_enable}" />
                                <input type=\'hidden\' name=\'image_path[]\' id=\'image_path_{picture_id}\' value=\'{image_full_path}\' />
                            </div>
                        </div>
                    </div>
                </li>
            </div>';

		$cropperModal = '
					<div id="cropper-modal" class="jbd-container" style="display: none">    
						<div class="jmodal-sm">
							<div class="jmodal-header">
								<p class="jmodal-header-title">'.JText::_("LNG_IMAGE_CROPPING").'</p>
								<a href="#close-modal" rel="modal:close" class="close-btn"><i class="la la-close "></i></a>
							</div>
							<div class="jmodal-body">
                                <p>'.JText::_("LNG_IMAGE_CROPPING_DESCRIPTION").'</p>
                                <br/>
                                <div>
                                    <img id="cropper-image" src="" />
                                </div>
				
                                <div class="row-fluid">
                                    <button type="button" id="save-cropped" class="btn btn-success mt-2">
                                        <span class="ui-button-text"><i class="la la-pencil"></i>'.JText::_("LNG_SAVE").'</span>
                                    </button>
                                    <button type="button" class="btn btn-dark mt-2" onclick="jQuery.jbdModal.close()">
                                        <span class="ui-button-text"><i class="la la la-close"></i>'.JText::_("LNG_CANCEL").'</span>
                                    </button>
                                </div>
                            </div>
						</div>
					</div>';

		if ($includeAttachments) {
			echo $attachmentTemplate;
		}

		if ($includeDropzonePictures) {
			echo $pictureTemplate;
		}

		if ($extraPictures) {
			echo $extraPictureTemplate;
		}

		if ($includeCropper) {
			echo $cropperModal;
		}
	}
  
	/**
	 * Retrieve the trial end date based on trial period unit and trial period amount
	 *
	 * @param      $package object details of the package
	 * @param null $date string the date from when the calculation will be made from, defaults to current date
	 *
	 * @return false|string
	 *
	 * @since 5.3.0
	 */
	public static function getTrialEndDate($package, $date = null) {
		if (empty($date)) {
			$date = date('Y-m-d');
		}
		
		$cycle = 'days';
		if ($package->trial_period_unit == 'M') {
			$cycle = 'months';
		} elseif ($package->trial_period_unit == 'Y') {
			$cycle = 'years';
		}
		
		$end = date('Y-m-d', strtotime("+".$package->trial_period_amount." $cycle", strtotime($date)));
		
		return $end;
	}

	/**
	 * Checks if a language constant has a translation for the active language.
	 *
	 * @param $languageConstant string
	 *
	 * @return bool
	 * @since 5.3.1
	 */
	public static function hasTranslation($languageConstant) {
		$result = strcmp(JText::_($languageConstant), $languageConstant) != 0;

		return $result;
	}

	/**
	 * Logs all the search parameters and values searched for
	 *
	 * @param $searchDetails array containing all searched parameters and values searched for
	 * @param $type int type of item where the search is done
	 *
	 * @return bool
	 *
	 * @throws Exception
	 * @since version
	 */
	public static function logSearch($searchDetails, $type) {
		$totalData = array();
		foreach ($searchDetails as $paramSearched => $searchedVal) {
			$dataToSave = array();
			if (strpos($paramSearched, 'keyword') !== false) {
				if (!empty($searchedVal)) {
					$dataToSave['item_type'] = SEARCH_LOG_KEYWORD;
					$dataToSave['value'] = $searchedVal;
					$dataToSave['has_text'] = 1;
				}
			} elseif (strpos($paramSearched, 'categoriesIds') !== false) {
				foreach ($searchedVal as $val) {
					$categories = explode(',', $val);
					$categories = array_filter($categories);
					foreach ($categories as $category) {
						$dataToSave['item_type'] = SEARCH_LOG_CATEGORY;
						$dataToSave['value'] = $category;
						$dataToSave['has_text'] = 0;
					}
				}
			} elseif (strpos($paramSearched, 'typeSearch') !== false) {
				if (!empty($searchedVal)) {
					$dataToSave['item_type'] = SEARCH_LOG_TYPE;
					$dataToSave['value'] = $searchedVal;
					$dataToSave['has_text'] = 0;
				}
			} elseif (strpos($paramSearched, 'latitude') !== false) {
				if (!empty($searchedVal)) {
					$dataToSave['item_type'] = SEARCH_LOG_LOCATION;
					$dataToSave['value'] = $searchedVal . "##" . $searchDetails['longitude'];
					$dataToSave['has_text'] = 1;
				}
			} elseif (strpos($paramSearched, 'countrySearch') !== false) {
				if (!empty($searchedVal)) {
					$dataToSave['item_type'] = SEARCH_LOG_COUNTRY;
					$dataToSave['value'] = $searchedVal;
					$dataToSave['has_text'] = 0;
				}
			} elseif (strpos($paramSearched, 'provinceSearch') !== false) {
				if (!empty($searchedVal)) {
					$dataToSave['item_type'] = SEARCH_LOG_PROVINCE;
					$dataToSave['value'] = $searchedVal;
					$dataToSave['has_text'] = 1;
				}
			} elseif (strpos($paramSearched, 'regionSearch') !== false) {
				if (!empty($searchedVal)) {
					$dataToSave['item_type'] = SEARCH_LOG_REGION;
					$dataToSave['value'] = $searchedVal;
					$dataToSave['has_text'] = 1;
				}
			} elseif (strpos($paramSearched, 'citySearch') !== false) {
				if (!empty($searchedVal)) {
					$dataToSave['item_type'] = SEARCH_LOG_CITY;
					$dataToSave['value'] = $searchedVal;
					$dataToSave['has_text'] = 1;
				}
			} elseif (strpos($paramSearched, 'minprice') !== false) {
				if (!empty($searchedVal)) {
					$dataToSave['item_type'] = SEARCH_LOG_MIN_PRICE;
					$dataToSave['value'] = $searchedVal;
					$dataToSave['has_text'] = 1;
				}
			} elseif (strpos($paramSearched, 'maxprice') !== false) {
				if (!empty($searchedVal)) {
					$dataToSave['item_type'] = SEARCH_LOG_MAX_PRICE;
					$dataToSave['value'] = $searchedVal;
					$dataToSave['has_text'] = 1;
				}
			} elseif (strpos($paramSearched, 'startDate') !== false) {
				if (!empty($searchedVal)) {
					$dataToSave['item_type'] = SEARCH_LOG_START_DATE;
					$dataToSave['value'] = $searchedVal;
					$dataToSave['has_text'] = 1;
				}
			} elseif (strpos($paramSearched, 'endDate') !== false) {
				if (!empty($searchedVal)) {
					$dataToSave['item_type'] = SEARCH_LOG_END_DATE;
					$dataToSave['value'] = $searchedVal;
					$dataToSave['has_text'] = 1;
				}
			} elseif (strpos($paramSearched, 'customAttributes') !== false) {
				if (!empty($searchedVal)) {
					JTable::addIncludePath(JPATH_ROOT . '/administrator/components/com_jbusinessdirectory/tables');
					$attrTable = JTable::getInstance("Attribute", "JTable");
					foreach ($searchedVal as $attrId => $val) {
						$attribute = $attrTable->getAttributesConfiguration($attrId)[0];
						if ($attribute->attributeTypeCode == 'input' || $attribute->attributeTypeCode == 'textarea'
							|| $attribute->attributeTypeCode == 'link' || $attribute->attributeTypeCode == 'header') {
							$dataToSave['has_text'] = 1;
							$dataToSave['value'] = $val;
						} else {
							$dataToSave['has_text'] = 0;
							$dataToSave['value'] = $val;
						}
						$dataToSave['item_type'] = SEARCH_LOG_CUSTOM_ATTRIBUTE;
					}
				}
			}
			if (!empty($dataToSave)) {
				$totalData[] = $dataToSave;
			}
		}

		if (!empty($totalData)) {
			$db =JFactory::getDBO();
			$created = self::convertToMysqlFormat(date('Y-m-d'));
			foreach ($totalData as $data) {
				$query = "insert into  #__jbusinessdirectory_search_logs (item_type, object_type, date, value, has_text) values 
			('".$db->escape($data['item_type'])."','".$db->escape($type)."','".$db->escape($created)."','".$db->escape($data['value'])."','".$db->escape($data['has_text'])."')";
				$db->setQuery($query);
				$db->execute();
			}
		}
		return true;
	}


	/**
	 * Get default payment processors
	 *
	 * @param bool $restrict restrict default processors based on the general settings selection
	 * @return array
	 */
	public static function getDefaultPaymentProcessors($restrict = false) {
		$defaultProcessors = array();
		
		$defaultProcessors['cash'] = JText::_('LNG_CASH');
		$defaultProcessors['wiretransfer'] = JText::_('LNG_WIRE_TRANSFER');
		$defaultProcessors['paypal'] = JText::_('LNG_PROCESSOR_PAYPAL');
		//$defaultProcessors['twocheckout'] = JText::_('LNG_PROCESSOR_2CHECKOUT');
		//$defaultProcessors['buckaroo'] = JText::_('LNG_PROCESSOR_BUCKAROO');
		//$defaultProcessors['cardsave'] = JText::_('LNG_PROCESSOR_CARDSAVE');
		//$defaultProcessors['eway'] = JText::_('LNG_PROCESSOR_EWAY');
		$defaultProcessors['payfast'] = JText::_('LNG_PROCESSOR_PAYFAST');
		$defaultProcessors['mollie'] = JText::_('LNG_PROCESSOR_MOLLIE');
		$defaultProcessors['touchpay'] = JText::_('LNG_PROCESSOR_TOUCHPAY');
		$defaultProcessors['payleo'] = JText::_('LNG_PROCESSOR_PAYLEO');

		if (self::isAppInstalled(JBD_APP_STRIPE)) {
			$defaultProcessors['stripeprocessor'] = JText::_('LNG_PROCESSOR_STRIPE');
		}
		
		if (self::isAppInstalled(JBD_APP_STRIPE_SUBSCRIPTIONS)) {
			$defaultProcessors['stripesubscriptions'] = JText::_('LNG_PROCESSOR_STRIPE_SUBSCRIPTIONS');
		}
		
		if (self::isAppInstalled(JBD_APP_AUTHORIZE)) {
			$defaultProcessors['authorize'] = JText::_('LNG_PROCESSOR_AUTHORIZE');
		}
		
		if (self::isAppInstalled(JBD_APP_AUTHORIZE_SUBSCRIPTIONS)) {
			$defaultProcessors['authorizesubscriptions'] = JText::_('LNG_PROCESSOR_AUTHORIZE_SUBSCRIPTIONS');
		}
		
		if (self::isAppInstalled(JBD_APP_PAYPAL_SUBSCRIPTIONS)) {
			$defaultProcessors['paypalsubscriptions'] = JText::_('LNG_PROCESSOR_PAYPAL_SUBSCRIPTIONS');
		}
		
		if (self::isAppInstalled(JBD_APP_PAYFAST_SUBSCRIPTIONS)) {
			$defaultProcessors['payfastsubscriptions'] = JText::_('LNG_PROCESSOR_PAYFAST_SUBSCRIPTIONS');
		}
		
		if (self::isAppInstalled(JBD_APP_MERCADO_PAGO)) {
            $defaultProcessors['mercadopagoprocessor'] = JText::_('LNG_PROCESSOR_MERCADO_PAGO');
        }

		$defaultProcessors['paymaya'] = JText::_('LNG_PROCESSOR_PAYMAYA');

		// restrict default processors based on the general settings selection
		if ($restrict) {
			$appSettings = JBusinessUtil::getApplicationSettings();
			$processorTypes = explode(',', $appSettings->default_processor_types);
			
			if(empty($processorTypes)){
				return array();
			} else {
				foreach ($defaultProcessors as $type=>$name) {
					if (!in_array($type, $processorTypes)) {
						unset($defaultProcessors[$type]);
					}
				}
			}
		}
		
		return $defaultProcessors;
	}

	/**
	 * Get  the default payment processor fields
	 *
	 * @return array payment processor fields
	 */
	public static function getPaymentProcessorFields() {
		$processorFieldsConfig =
		array(
				"stripeprocessor" => array(
						"name" => "Stripe",
						"type" => "stripeprocessor",
						"fields" => array(
								"secret_key"      => JText::_("LNG_SECRET_KEY"),
								"publishable_key" => JText::_("LNG_PUBLISHABLE_KEY")
						)
				),
				"stripesubscriptions" => array(
						"name" => "Stripe Subscriptions",
						"type" => "stripesubscriptions",
						"fields" => array(
								"secret_key"      => JText::_("LNG_SECRET_KEY"),
								"publishable_key" => JText::_("LNG_PUBLISHABLE_KEY")
						)
				),
				"paypal" => array(
						"name" => "Paypal",
						"type" => "paypal",
						"fields" => array(
								"paypal_email" => JText::_("LNG_PAYPAL_EMAIL")
						)
				),
				"paypalsubscriptions" => array(
						"name" => "Paypal Subscriptions",
						"type" => "paypalsubscriptions",
						"fields" => array(
								"paypal_email" => JText::_("LNG_PAYPAL_EMAIL")
						)
				),
				"payfast" => array(
						"name" => "Payfast",
						"type" => "payfast",
						"fields" => array(
								"merchant_id" => JText::_("LNG_MERCHANT_ID"),
								"merchant_key" => JText::_("LNG_MERCHANT_KEY"),
								"passphrase" => JText::_("LNG_PASSPHRASE")
						)
				),
				"payfastsubscriptions" => array(
						"name" => "Payfast Subscriptions",
						"type" => "payfastsubscriptions",
						"fields" => array(
								"merchant_id" => JText::_("LNG_MERCHANT_ID"),
								"merchant_key" => JText::_("LNG_MERCHANT_KEY"),
								"passphrase" => JText::_("LNG_PASSPHRASE")
						)
				),
				"authorize" => array(
						"name" => "Authorize",
						"type" => "authorize",
						"fields" => array(
								"transaction_key" => JText::_("LNG_TRANSACTION_KEY"),
								"api_login_id" => JText::_("LNG_API_LOGIN_ID")
						)
				),
				"authorizesubscriptions" => array(
						"name" => "Authorize Subscriptions",
						"type" => "authorizesubscriptions",
						"fields" => array(
								"transaction_key" => JText::_("LNG_TRANSACTION_KEY"),
								"api_login_id" => JText::_("LNG_API_LOGIN_ID")
						)
				),
				"wiretransfer" => array(
						"name" => "Bank Transfer",
						"type" => "wiretransfer",
						"fields" => array(
								"bank_name" => JText::_("LNG_BANK_NAME"),
								"bank_city" => JText::_("LNG_BANK_CITY"),
								"bank_address" => JText::_("LNG_BANK_ADDRESS"),
								"bank_country" => JText::_("LNG_BANK_COUNTRY"),
								"swift_code" => JText::_("LNG_SWIFT_CODE"),
								"iban" => JText::_("LNG_IBAN"),
								"bank_account_number" => JText::_("LNG_BANK_ACCOUNT_NUMBER"),
								"bank_holder_name" => JText::_("LNG_BANK_HOLDER_NAME"),
						)
				),
				"buckaroo" => array(
						"name" => "Buckaroo",
						"type" => "buckaroo",
						"fields" => array(
								"secretKey" => JText::_("LNG_SECRETKEY"),
								"merchantId" => JText::_("LNG_MERCHANT_ID"),
						)
				),
				"cardsave" => array(
						"name" => "Cardsave",
						"type" => "cardsave",
						"fields"  => array(
								"secretKey" => JText::_("LNG_SECRETKEY"),
								"preSharedKey" => JText::_("LNG_PRESHARED_KEY"),
								"password" => JText::_("LNG_PASSWORD"),
						)
				),
				"eway" => array(
						"name" => "Eway",
						"type" => "eway",
						"fields" => array(
								"user_name" => JText::_("LNG_USER_NAME"),
								"customer_id" => JText::_("LNG_CUSTOMER_ID")
						)
				),
				"twocheckout" => array(
						"name" => "2Checkout",
						"type" => "twocheckout",
						"fields" => array(
								"account_number" => JText::_("LNG_ACCOUNT_NUMBER"),
								"secret_word" => JText::_("LNG_SECRET_WORD")
						)
				),
				"mollie" => array(
						"name" => "Mollie",
						"type" => "mollie",
						"fields" => array(
								"api_key" => JText::_("LNG_API_KEY")
						)
				),
				"touchpay" => array(
						"name" => "Touch Pay",
						"type" => "touchpay",
						"fields" => array(
							"agency_code" => JText::_('LNG_AGENCY_CODE'),
							"security_code" => JText::_('LNG_SECURITY_CODE')
						)
				),
				"payleo" => array(
					"name" => "Pay Leo",
					"type" => "payleo",
					"fields" => array(
						"consumer_key" => JText::_('LNG_CONSUMER_KEY'),
						"consumer_secret" => JText::_('LNG_CONSUMER_SECRET'),
						"customer_msisdn" => JText::_('LNG_CUSTOMER_MSISDN'),
						"merchant_code"  => JText::_('LNG_MERCHANT_CODE')
					)
				),
                "mercadopagoprocessor" => array(
                    "name" => "Mercado Pago",
                    "type" => "mercadopagoprocessor",
                    "fields" => array(
                        "public_key" => JText::_('LNG_PUBLIC_KEY'),
                        "access_token" => JText::_('LNG_ACCESS_TOKEN'),
                    )
				),
				"paymaya" => array(
					"name" => "PayMaya",
					"type" => "paymaya",
					"fields" => array(
							"secret_key"      => JText::_("LNG_SECRET_KEY"),
							"publishable_key" => JText::_("LNG_PUBLISHABLE_KEY")
					)
				),
		);
		
		return $processorFieldsConfig;
	}

	/**
	 * Check if payment processor should be available for assignment
	 *
	 * @return bool
	 */
	public static function canAssignPaymentProcessor($restrict = false) {
		if (self::isAppInstalled(JBD_APP_SELL_OFFERS) || self::isAppInstalled(JBD_APP_APPOINTMENTS) || self::isAppInstalled(JBD_APP_EVENT_BOOKINGS)) {
			$appSettings = JBusinessUtil::getApplicationSettings();
			
			$defaultProcessors = JBusinessUtil::getDefaultPaymentProcessors($restrict);

			if(empty($defaultProcessors)){
				return false;
			}

			if ($appSettings->enable_offer_selling || $appSettings->enable_event_reservation || $appSettings->enable_services) {
				return true;
			} else {
				return false;
			}
			return $filtersHidden;
		}
	}
	
	/**
	 * Set the filter visibility status.
	 * Check if any option is selected and if yes keep the filter open by default.
	 *
	 * @param $state
	 * @return int 1 if the filter need to be hidden or 0 if it need to be shown
	 *
	 * @since 5.3.3
	 */
	public static function setFilterVisibility($state) {
		$filtersHidden = 1; // by default keep the filter hidden

		//if any state is set than make it visible
		if ($state->get('filter.company_id') != ''      ||  $state->get('filter.status_id') != ''   ||
			$state->get('filter.published') != ''       ||  $state->get('filter.state_id') != ''    ||
			$state->get('filter.type_id') != ''         ||  $state->get('filter.category_id') != '' ||
			$state->get('filter.type') != ''            ||  $state->get('filter.package_id') != ''  ||
			$state->get('filter.start_date') != ''      ||  $state->get('filter.end_date') != ''    ||
			$state->get('filter.item_type') != ''       ||  $state->get('filter.object_type') != '' ||
			$state->get('filter.service_id') != ''      ||  $state->get('filter.location_id') != '' ||
			$state->get('filter.conference_id') != ''   ||  $state->get('filter.level_id') != ''    ||
			$state->get('filter.event_id') != ''        ||  $state->get('filter.status') != ''      ||
			$state->get('filter.attribute_type') != ''  ||  $state->get('filter.payment_status_id') != ''
		) {
			$filtersHidden = 0;
		}

		return $filtersHidden;
	}
	
	/**
	 * Convert a string date range to 2 dates
	 *
	 * @param unknown $dateRange
	 * @return stdClass
	 */
	public static function processDateRange($dateRange) {
		$dates = explode(':', $dateRange);

		$result = new stdClass();
		$result->startDate = isset($dates[0])?self::convertToMysqlFormat($dates[0]):"";
		$result->endDate = isset($dates[1])?self::convertToMysqlFormat($dates[1]):"";
		
		return $result;
	}

	/**
	 * Check if user has access to item edit view on CP front end. If the user has no rights to access the item he will
	 * be redirected to list view containing that item.
	 *
	 * @param $itemId integer Id of the item trying to be accessed
	 * @param $itemUserId integer Owner of item trying to be accessed
	 * @param $companyId integer Company if related to the item trying to be accessed
	 * @param $view string list view that contains the item
	 * @throws Exception
	 * @since 5.4.0
	 */
	public static function checkEditAccessForItem($itemId, $itemUserId, $companyId, $view) {
		$user = JBusinessUtil::getUser();
		$companies = self::getCompaniesByUserId();
		$found = false;

		if ($itemUserId == $user->id) {
			$found = true;
		} else {
			foreach ($companies as $company) {
				if ($company->userId == $user->id && $companyId == $company->id) {
					$found = true;
				}
			}
		}


		//redirect if the user has no access and the event appointment is not new
		if (!$found && $itemId != 0) {
			$msg = JText::_("LNG_ACCESS_RESTRICTED");
			$app = JFactory::getApplication();
			$app->redirect(JRoute::_('index.php?option=com_jbusinessdirectory&view='.$view, $msg));
		}
	}


	/**
	 * Retrieve the list of available services
	 *
	 * @return array available services
	 */
	public static function getAvailablePayableServices($front=false) {
		$instance = JBusinessUtil::getInstance();
		
		if (!isset($instance->paidServices)) {
			$paidServices  = array();
			
			JTable::addIncludePath(JPATH_ROOT . '/administrator/components/com_jbusinessdirectory/tables');
			$directoryAppsTable = JTable::getInstance("DirectoryApps", "JTable");
			$services           = $directoryAppsTable->getDirectoryApps();
			
			$payableServices = array(JBD_APP_APPOINTMENTS, JBD_APP_EVENT_BOOKINGS, JBD_APP_SELL_OFFERS, JBD_APP_CAMPAIGNS, JBD_PACKAGES);
			if($front){
				$payableServices = array(JBD_APP_APPOINTMENTS, JBD_APP_EVENT_BOOKINGS, JBD_APP_SELL_OFFERS);
			}

			foreach ($services as $service) {
				if (JBusinessUtil::isAppInstalled($service->id) && in_array($service->id, $payableServices)) {
					$paidServices[] = $service;
				}
			}
			
			if(!$front){
				$packageOption = new stdClass();
				$packageOption->id = JBD_PACKAGES;
				$packageOption->name = JText::_("LNG_PACKAGES");
				$paidServices[] = $packageOption;
			}

			$instance->paidServices = $paidServices;
		}
		
		return $instance->paidServices;
	}
	
	/**
	 * Retrieve the app ids and return the app names
	 *
	 * @param array $appIds
	 */
	public static function getSelectedServicesNames($appIds) {
		$result = array();
		$apps = self::getAvailablePayableServices();
		foreach ($appIds as $id) {
			foreach ($apps as $app) {
				if ($app->id == $id) {
					$result[] = $app->name;
				}
			}
		}
		
		return $result;
	}

	/**
	 * Return All Listing Types
	 *
	 * @return mixed
	 * @since 5.4.0
	 */
	public static function getListingTypes() {
		$db = JFactory::getDbo();
		$query = $db->getQuery(true)
			->select('id AS value, name AS name')
			->from('#__jbusinessdirectory_company_types')
			->order('ordering ASC');

		$db->setQuery($query);
		return $db->loadObjectList();
	}

	/**
	 * check if JCH plugin option for try_catch is yes or no
	 * @throws Exception
	 */
	public static function checkJCHPlugin() {
		$plugin = JPluginHelper::getPlugin('system', 'jch_optimize');
		if ($plugin) {
			$pluginParams = new JRegistry($plugin->params);
			$tryCatch = $pluginParams->get('try_catch');
			if ($tryCatch) {
				JFactory::getApplication()->enqueueMessage(JText::_('LNG_JCH_OPTIONS_WARNING'), 'danger');
			}
		}
	}

	/**
	 * Get All payment statuses options
	 *
	 * @return array containing the payment statuses
	 *
	 * @since version
	 */
	public static function getPaymentStatuses(){
		$statuses      = array();
		$status        = new stdClass();
		$status->value = PAYMENT_STATUS_PAID;
		$status->text  = JText::_("LNG_PAYMENT_STATUS_PAID");
		$statuses[]    = $status;
		$status        = new stdClass();
		$status->value = PAYMENT_STATUS_NOT_PAID;
		$status->text  = JText::_("LNG_PAYMENT_STATUS_NOT_PAID");
		$statuses[]    = $status;
		$status        = new stdClass();
		$status->value = PAYMENT_STATUS_FAILURE;
		$status->text  = JText::_("LNG_PAYMENT_STATUS_FAILURE");
		$statuses[]    = $status;
		$status        = new stdClass();
		$status->value = PAYMENT_STATUS_CANCELED;
		$status->text  = JText::_("LNG_PAYMENT_STATUS_CANCELED");
		$statuses[]    = $status;
		$status        = new stdClass();
		$status->value = PAYMENT_STATUS_WAITING;
		$status->text  = JText::_("LNG_PAYMENT_STATUS_WAITING");
		$statuses[]    = $status;
		$status        = new stdClass();
		$status->value = PAYMENT_STATUS_PENDING;
		$status->text  = JText::_("LNG_PAYMENT_STATUS_PENDING");
		$statuses[]    = $status;

		return $statuses;
    }

	/**
	 * Get Offer Order states
	 *
	 * @return array
	 *
	 * @since 5.0.0
	 */
	public static function getOfferOrderStates() {
		$statuses      = array();
		$status        = new stdClass();
		$status->value = OFFER_ORDER_CREATED;
		$status->text  = JText::_("LNG_CREATED");
		$statuses[]    = $status;
		$status        = new stdClass();
		$status->value = OFFER_ORDER_CONFIRMED;
		$status->text  = JText::_("LNG_CONFIRMED");
		$statuses[]    = $status;
		$status        = new stdClass();
		$status->value = OFFER_ORDER_SHIPPED;
		$status->text  = JText::_("LNG_SHIPPED");
		$statuses[]    = $status;
		$status        = new stdClass();
		$status->value = OFFER_ORDER_COMPLETED;
		$status->text  = JText::_("LNG_COMPLETED");
		$statuses[]    = $status;

		return $statuses;
	}

	/**
	 * Get Event Reservation States options
	 *
	 * @return array
	 *
	 * @since version
	 */
	public static function getEventReservationStates()
	{
		$statuses = array();
		$status = new stdClass();
		$status->value = EVENT_BOOKING_CREATED;
		$status->text = JTEXT::_("LNG_CREATED");
		$statuses[] = $status;
		$status = new stdClass();
		$status->value = EVENT_BOOKING_CONFIRMED;
		$status->text = JTEXT::_("LNG_CONFIRMED");
		$statuses[] = $status;
		$status = new stdClass();
		$status->value = EVENT_BOOKING_CANCELED;
		$status->text = JTEXT::_("LNG_CANCELED");
		$statuses[] = $status;

		return $statuses;
	}

	/**
	 * Get all company Service bookings state options
	 * @return array
	 *
	 * @since version
	 */
	public static function getCompanyServiceReservationStates() {
		$statuses      = array();
		$status        = new stdClass();
		$status->value = SERVICE_BOOKING_CREATED;
		$status->text  = JText::_("LNG_CREATED");
		$statuses[]    = $status;
		$status        = new stdClass();
		$status->value = SERVICE_BOOKING_CONFIRMED;
		$status->text  = JText::_("LNG_CONFIRMED");
		$statuses[]    = $status;
		$status        = new stdClass();
		$status->value = SERVICE_BOOKING_CANCELED;
		$status->text  = JText::_("LNG_CANCELED");
		$statuses[]    = $status;

		return $statuses;
	}

    /**
     * Get Company Service types
     *
     * @return array
     *
     * @since version
     */
    public static function getServiceTypes()
    {
        $statuses = array();
        $status = new stdClass();
        $status->value = SERVICE_TYPE_LIVE;
        $status->text = JTEXT::_("LNG_LIVE");
        $statuses[] = $status;
        $status = new stdClass();
        $status->value = SERVICE_TYPE_VIRTUAL;
        $status->text = JTEXT::_("LNG_VIRTUAL");
        $statuses[] = $status;
        $status = new stdClass();
        $status->value = SERVICE_TYPE_MIXED;
        $status->text = JTEXT::_("LNG_MIXED");
        $statuses[] = $status;

        return $statuses;
    }

	/**
	 * Generate the review statistics by stars
	 * @param unknown $reviews
	 * @return array[]|unknown
	 */
	public static function getReviewsStatistics($reviews){
		$reviewsStatistics = array('1'=>array(),'2'=>array(),'3'=>array(),'4'=>array(),'5'=>array());
		foreach ($reviews as $review){
			$reviewsStatistics[round($review->rating)][] = $review;
		}
		return $reviewsStatistics;
	}
	
	/**
	 * Calculate the average rating
	 * 
	 * @param unknown $reviews
	 * @return array[]|unknown
	 */
	public static function getReviewsAverageScore($reviews){
		if(empty($reviews)){
			return 0;
		}
		
		$score = 0;
		foreach($reviews as $review){
			$score += $review->rating;
		}
		
		$score = $score*1.0/count($reviews);
			
		return $score;
			
	}

    /**
     *
     * Get the total unread messages for a user
     *
     * @param $userId
     * @return mixed
     */
	public static function getTotalUserMessages($userId, $onlyUnread = false){
        JTable::addIncludePath(JPATH_ROOT . '/administrator/components/com_jbusinessdirectory/tables');
        $messagesTable = JTable::getInstance("Messages", "JTable");

        $companiesIds = self::getCompaniesByUserId($userId);
        $companiesIds = array_column($companiesIds, 'id');

        $result = $messagesTable->getTotalMessages($userId, $companiesIds, 0,$onlyUnread);

		if(empty($result)){
			return 0;
		}

        return $result;
    }


    /**
     * Get Event attendance modes
     *
     * @return array
     *
     * @since version
     */
    public static function getAttendanceModes()
    {
        $statuses = array();
        $status = new stdClass();
        $status->value = MODE_LIVE;
        $status->text = JTEXT::_("LNG_LIVE");
        $statuses[] = $status;
        $status = new stdClass();
        $status->value = MODE_VIRTUAL;
        $status->text = JTEXT::_("LNG_VIRTUAL");
        $statuses[] = $status;
        $status = new stdClass();
        $status->value = MODE_MIXED;
        $status->text = JTEXT::_("LNG_MIXED");
        $statuses[] = $status;

        return $statuses;
    }

    /**
     * Get attendance mode text
     *
     * @param $mode
     */
    public static function getAttendanceModeText($mode){
        $modes = self::getAttendanceModes();
        foreach($modes as $md){
            if($md->value == $mode){
                return $md->text;
            }
        }

        return "";
    }

    /**
     * Get month names
     *
     */
    public static function getMonthNames(){
        $monthNames = array();
        for ($i = 1; $i <= 12; $i++) {
            $monthNames[] = JBusinessUtil::monthToString($i, false);
        }

        return $monthNames;
    }

    /**
     * Get short month names
     *
     */
    public static function getShortMonthNames(){
        $monthNamesShort = array();
        for ($i = 1; $i <= 12; $i++) {
            $monthNamesShort[] = JBusinessUtil::monthToString($i, true) ;
        }

        return $monthNamesShort;
    }

    /**
     * Formats response as json and prints it
     *
     * @param $response object
     *
     * @since 5.3.0
     */
    public static function sendJsonResponse($data, $status, $message="") {
        $response          = new stdClass();
        $response->data    = $data;
        $response->status  = $status;
        $response->message = $message;

	    if (ob_get_length() > 0 ) {
			ob_end_clean();
		}

        // Send as JSON
        header("Content-Type: application/json", true);
        echo json_encode($response);
        exit;
	}
	
	/**
     * Include jQuery UI based on Joomla version
     *
     */
	public static function loadJQueryUI () {	

		if (self::isJoomla3()) {			

			JHtml::_('jquery.ui', array('core', 'sortable'));
			if (!defined('J_JQUERY_UI_LOADED')) {
				JBusinessUtil::enqueueStyle('libraries/jquery/jquery-ui.css');
				JBusinessUtil::enqueueScript('libraries/jquery/jquery-ui.js');
			
				define('J_JQUERY_UI_LOADED', 1);
			}
		} else {
			JBusinessUtil::enqueueStyle('libraries/jquery/jquery-ui.css');			
			JBusinessUtil::enqueueScript('libraries/jquery/jquery-ui.js');
		}

	}

	/**
     * Check if there is no other appointment booked at the same time for an user
     *
	 * @param $userId int id of user creating the booking
	 * @param $date string date of appointment
	 * @param $time string time of appointment
     */
	public static function checkAppointmentAvailability ($userId, $date, $time, $bookingId) {		
		$appointmentTable = JTable::getInstance("companyservicebookings", "JTable");
		$result = $appointmentTable->checkAvailability($userId, $date, $time, $bookingId);
		
		return $result;
	}
    /* Fetches and returns all countries
     *
	 * @return array
     *
     * @since 5.5.0
	 */
	public static function getCountries() {
		JTable::addIncludePath(JPATH_ROOT.'/administrator/components/com_jbusinessdirectory/tables');
		$countriesTable = JTable::getInstance("Country", "JTable");
		$countries = $countriesTable->getCountries();

		return $countries;
	}
	
	/* Initialize chosen on Joomla3
     *
	 */
	public static function initializeChosen () {		
		if(self::isJoomla3()){
			JHtml::_('formbehavior.chosen', 'select');
		}		
    }

	/**
	 * Load the jquery chosen library
	 */
	public static function loadJQueryChosen() {
		JBusinessUtil::enqueueScript('libraries/chosen/chosen.jquery.min.js');
		JBusinessUtil::enqueueStyle('libraries/chosen/chosen.css');
	}
    /**
     *
     * Get the total unread quote requests for a user related companies
     *
     * @param $userId
     * @return mixed
     */
    public static function getUnreadUserQuotes($userId){
       JTable::addIncludePath(JPATH_ROOT . '/administrator/components/com_jbusinessdirectory/tables');
       $quoteTable = JTable::getInstance("requestquote", "JTable");

       $companyIds = self::getCompaniesByUserId($userId, true);
       
	   if(!empty($companyIds)){
			$companyIds = implode(',', $companyIds);
       		$result = $quoteTable->getTotalQuoteRequests($companyIds, true);
			return $result;
	   }

	   return null;
    }

	/**
     * Return packages prices with VAT included
     *
	 * @param $packages
     * @since 5.5.0
	 */
    public static function packagesPriceVat($packages){
        $appSettings = JBusinessUtil::getApplicationSettings();
        if($appSettings->packages_vat_apply) {
            foreach($packages as &$package) {
                $package->price += TaxService::getVatAmount($package->price);
            }
        }
    }

	/**
     * Retuns the HTML for the RSS Modal
     *
	 * @param $categoryOptions array of categories
	 *
	 * @return string
	 * @throws Exception
     *
     * @since 5.5.0
	 */
    public static function getRssModal($categoryOptions) {
        return '<div class="jbd-container" id="rss-model" style="display: none">
                <form action="'.JRoute::_("index.php?option=com_jbusinessdirectory&view=catalog").'" method="get" name="rssForm" id="rssForm">
                    <div class="jmodal-sm">
                        <div class="jmodal-header">
                            <p class="jmodal-header-title">'.JText::_("LNG_COMPANIES_RSS").'</p>
                            <a href="#close-modal" rel="modal:close" class="close-btn"><i class="la la-close "></i></a>
                        </div>
                        <div class="jmodal-body">
                            <p>'.JText::_("LNG_CATEGORY_RSS_TEXT").'</p>
                            <div class="row">
                                <div class="col-12">
                                    <div class="jinput-outline jinput-hover">
                                        <select name="category" id="category" class="form-control chosen-select">
                                            <option value="0">'.JText::_("LNG_ALL_CATEGORIES").'</option>
                                            '.JHtml::_("select.options", $categoryOptions, "value", "text", null).'
                                        </select>
                                    </div>
                                </div>
                            </div>
                            <input type="hidden" name="option"	value="'.JBusinessUtil::getComponentName().'" />
                            <input type="hidden" name="task" id="task" value="directoryrss.getCompaniesRss" />
                            '.JHTML::_( "form.token" ).'
                        </div>
                        <div class="jmodal-footer">
                            <div class="btn-group" role="group" aria-label="">
                                <button type="button" class="jmodal-btn jmodal-btn-outline" onclick="jQuery.jbdModal.close()">'.JText::_("LNG_CANCEL").'</button>
                                <button type="submit" class="jmodal-btn">'.JText::_("LNG_GENERATE").'</button>
                            </div>
                        </div>
                    </div>
                </form>
            </div>';
    }

    /**
     * Detects if client browser is IE11 or below.
     *
     * @return bool
     *
     * @since 5.5.1
     */
    public static function isBrowserIE11() {
        if (preg_match('~MSIE|Internet Explorer~i', $_SERVER['HTTP_USER_AGENT']) || preg_match('~Trident/7.0(; Touch)?; rv:11.0~',$_SERVER['HTTP_USER_AGENT'])) {
            // is IE 11 or below
            return true;
        }

        return false;
    }


    /**
    *
	* @param $string
    * @return string Function to check and format the content to UTF-8 Encoding
    */
	public static function make_safe_for_utf8_use($string) {
		$encoding = mb_detect_encoding($string, "UTF-8,WINDOWS-1252");

		if ($encoding != 'UTF-8') {
			return iconv($encoding, 'UTF-8//TRANSLIT', $string);
		} else {
			return $string;
		}
	}

	/**
	 * Retrieve the unique sessios days
	 */
	public static function getSessionsDays($sessions){
		$result = array();

		if(empty($sessions)){
			return $result;
		}

		foreach($sessions as $session){
			if(!in_array($session->date, $result)){
				$result[]=$session->date;
			}
		}

		return $result;
	}

	public static function array_search_recursive($needle, $haystack) {
		foreach ($haystack as $value) {
			if (is_array($value) && self::array_search_recursive($needle, $value)) {
				return true;
			}
			else if ($value == $needle) {
				return true;
			}
		}
		return false;
	}

	public static function check_time_overlap($start_time1, $end_time1, $start_time2, $end_time2) {
		if ($start_time1 <= $end_time2 && $start_time2 < $end_time1) {
			return true;
		}
		return false;
	}

	public static function getOverlappingSessions($session) {

		$user = JBusinessUtil::getUser();
		$registersTable = JTable::getInstance("SessionRegister", "JTable");
		$userRegisteredSessions = $registersTable->getUserSessionRegistrations($user->id);

		$overlaps = array();
		if(!empty($userRegisteredSessions)) {
			foreach($userRegisteredSessions as $registration) {
				if($registration->id != $session->id && $registration->date == $session->date) {
					$isOverlap = self::check_time_overlap($session->start_time, $session->end_time, $registration->start_time, $registration->end_time);
					if ($isOverlap) {
						$overlaps[] = $registration->id;
					}
				}
			}
		}
		return $overlaps;
	}


	/**
	 * Adds the possibility to sort items using drag&drop in the list views
	 *
	 *
	 */
	public static function addSorting($saveOrder=null, $listDirn=null) {

		$jinput = JFactory::getApplication()->input;
		$task = $jinput->get( 'view' );

		$saveOrderingUrl="";

		$listType = 'itemList';
		if($task == 'categories') {
			$listType = 'categoryList';
		}

		if ($saveOrder) {
			if (defined('JVERSION')) {
				$joomlaVersion = (int)JVERSION;
			} else {
				$j = new JVersion();
				$joomlaVersion = (int)$j->getShortVersion();
			}
			$saveOrderingUrl = 'index.php?option=com_jbusinessdirectory&task='.$task.'.saveOrderAjax&tmpl=component&' . JSession::getFormToken() . '=1';
			if ($joomlaVersion == 3) {
				JHtml::_('sortablelist.sortable', $listType , 'adminForm', strtolower($listDirn), $saveOrderingUrl, false, true);
			} else {
				HTMLHelper::_('draggablelist.draggable');
			}
		}

		return $saveOrderingUrl;
	}

	public static function convertHexToRGB($color, $opacity=null, $pdf = false){
		list($r, $g, $b) = sscanf($color, "#%02x%02x%02x");
		if(!empty($opacity)){
			$result = "rgba($r,$g,$b,$opacity)";
		} elseif ($pdf) {
			$result = array($r,$g,$b);
		}else{
			$result = "rgba($r,$g,$b)";
		}

		return $result;
	}

	public static function renderCategoryIcon ($icon=null, $image=null, $attributes=null) {
		$appSettings = self::getApplicationSettings();

		$result = '';
		if (!empty($image) ) {
			$result = '<img src="'.BD_PICTURES_PATH.$image.'" alt="icon-'.$image.'" class="category-icon-image" >';
		} else {
			$result = '<i class="la la-'.$icon.' '.$attributes.'"></i>';
		}

		return $result;
	}

	/**
     *Returns the url for an article
     *@param $articleId id of the article
     *
     */
	public static function getArticleUrl($articleId) {
		$db = JFactory::getDbo();
		$query = $db->getQuery(true)
			->select('a.id, a.alias, a.catid, a.language');
		$query->from('#__content AS a')
			->where('a.id = ' . (int) $articleId);


		$db->setQuery($query);
		$data = $db->loadObject();

		$url="";
		if(!empty($data)) {
			//JLoader::register('ContentHelperRoute', JPATH_SITE . '/components/com_content/helpers/route.php');
			//$url = JRoute::_(ContentHelperRoute::getArticleRoute($data->id, $data->catid));
			$url = JRoute::_('index.php?option=com_content&view=article&id=' . $data->id, false);

			return $url;
		}

	}

	/**
     *Returns the url for the terms and conditions article
     *You specify the id of article being retrieved in general settings
     *
     */
	public static function getTermsAndConditions ($type = 'general') {
		$instance = JBusinessUtil::getInstance();
		$appSettings = JBusinessUtil::getApplicationSettings();

		if ($type=='contact') {
			if (!isset($instance->contactTermsConditionsUrl)) {
				$articleId = (int)$appSettings->contact_terms_conditions_article_id;
				$instance->contactTermsConditionsUrl = self::getArticleUrl($articleId);
			}
			return $instance->contactTermsConditionsUrl;
		}elseif ($type=="reviews") {
			if (!isset($instance->reviewTermsConditionsUrl)) {
				$articleId = (int)$appSettings->reviews_terms_conditions_article_id;
			   $instance->reviewTermsConditionsUrl = self::getArticleUrl($articleId);
		   }
		   return $instance->reviewTermsConditionsUrl;
		}elseif ($type=="privacy") {
			if (!isset($instance->privacyPolicyUrl)) {
				$articleId = (int)$appSettings->privacy_policy_article_id;
			   $instance->privacyPolicyUrl = self::getArticleUrl($articleId);
		   }
		   return $instance->privacyPolicyUrl;
		} else {
			if(!isset($instance->termsConditionsUrl)) {
				$articleId = (int)$appSettings->terms_conditions_article_id;
				$instance->termsConditionsUrl = self::getArticleUrl($articleId);
			}
			return $instance->termsConditionsUrl;
		}
	}

	/**
     *Returns the url to view the terms and conditions
     *If setting is enabled in general settings you view terms in article
     *otherwise they are displayed in termsconditions view
     */
	public static function getTermsUrl ($type = 'general') {
		$appSettings = JBusinessUtil::getApplicationSettings();

		if($appSettings->show_terms_conditions_article == 1) {
			$termsConditionsUrl = self::getTermsAndConditions($type);
		} else {
			$termsConditionsUrl = JRoute::_('index.php?option=com_jbusinessdirectory&view=termsconditions&type='.$type);
		}

		return $termsConditionsUrl;
	}

	/**
     *Renders the Terms and Conditions and Privacy policy html
     *@param $type  Type of the Terms and Conditions to retrieve
     *
     */
	public static function renderTermsAndConditions($type = 'general') {

		$appSettings = JBusinessUtil::getApplicationSettings();

		if($type=='reviews') {
			$termsText = JText::_('LNG_REVIEW_TERMS_AGREAMENT');
		} elseif($type=='contact') {
			$termsText = JText::_('LNG_CONTACT_TERMS_AGREAMENT');
		} else {
			$termsText = JText::_('LNG_TERMS_AGREAMENT');
		}

		$termsUrl = '<a target="_blank" href="'.JBusinessUtil::getTermsUrl($type).'" >'.JText::_('LNG_TERMS_AND_CONDITIONS').'</a>';
		$termsAgreement = str_replace("{terms_link}", $termsUrl, $termsText);
		$privacyUrl = '<a target="_blank" href="'.JBusinessUtil::getTermsUrl('privacy').'" >'.JText::_('LNG_PRIVACY_POLICY').'</a>';
		$privacyAgreement = str_replace("{privacy_link}", $privacyUrl, JText::_('LNG_PRIVACY_AGREEMENT'));

		$html = '<div id="term_conditions" class="jbd-terms-conditions">';
		$html .= '<p class="small">'.$termsAgreement;
		if($appSettings->show_privacy == 1) {
			$html .= $privacyAgreement .' </p>';
		} else {
			$html .= '</p>';
		}
		$html .= '</div>';

		return $html;
	}

	/**
	 * Resize an image
	 *
	 */
	public static function resizeImage($imagePath, $maxWidth=500, $maxHeight=500){
		require_once HELPERS_PATH.'/class.resizeImage.php';

		$image = new Resize_Image;
		$image->ratio = true;

		if (!empty($maxWidth)) {
			$image->new_width = $maxWidth;
		}else if(!empty($maxHeight)) {
			$image->new_height = $maxHeight;
		}

		$file_tmp      = JBusinessUtil::makePathFile($imagePath);

		$image->image_to_resize = $file_tmp;    // Full Path to the file

		$image->new_image_name = basename($file_tmp);
		$image->save_folder    = dirname($file_tmp) . DIRECTORY_SEPARATOR;

		$process = $image->resize();
		if ($process['result'] && $image->save_folder) {
			return true;
		}

		return false;
	}

	/**
	 * Get the thumnail file name from the original file
	 *
	 */
	public static function getThumbnailImage($image){
		$extension = pathinfo($image, PATHINFO_EXTENSION);
		$baseName = basename($image, ".{$extension}");
		$thumbImage =str_replace($baseName,"{$baseName}_thumb",$image);

		return $thumbImage;
	}

	public static function getLoginUrl($redirect = null, $amp=true) {

		if(!isset($redirect)) {
			$base_url = ( isset($_SERVER['HTTPS']) && $_SERVER['HTTPS']=='on' ? 'https' : 'http' ) . '://' .  $_SERVER['HTTP_HOST'];
			$redirect = $base_url . $_SERVER["REQUEST_URI"];
		}

		$redirect = base64_encode($redirect);
		$result = JRoute::_('index.php?option=com_users&view=login&return='.$redirect, $amp);

		return $result;
	}

	/**
	 * Retrieve the fist listing of the user when there are no orders generated
	 * This is used for showing an upgrade message on the front-end CP
	 *
	 */
	public static function getUpgradeListingID($userId){
		JTable::addIncludePath(JPATH_ROOT.'/administrator/components/com_jbusinessdirectory/tables');
		$orderTable = JTable::getInstance("Order", "JTable", array());
		$orders = $orderTable->getOrders($userId);

		if(empty($orders)){
			$listings = self::getCompaniesOptions(-1,$userId);
			if(!empty($listings)){
				return $listings[0]->id;
			}
		}

		return null;
	}

	public static function formatToDefaultDate($dateString) {
		$app = JBusinessUtil::getApplicationSettings();
		
		$dateFormat = $app->dateFormat;
		$formattedAvailableDates = '';
		if (isset($dateString) && !empty($dateString)) {
			$dates = explode(",", $dateString);
			$result = array();
			foreach ($dates as $date) {
				if ($date=="NaN-NaN-NaN") {
					continue;
				}
				$dateObj = new DateTime($date);
				$formatedDate = $dateObj->format($dateFormat);
				$result[] = $formatedDate;
			}
		
			$formattedAvailableDates = implode(",", $result);
		}
		
		return $formattedAvailableDates;
	}

	/**
	 * render user selection
	 *
	 * @return rendered content
	 */
	public static function renderUserSelection($name, $userId, $vName){
		
		if(!JBusinessUtil::isJoomla3()){

			HTMLHelper::_('bootstrap.modal');
			Factory::getDocument()->getWebAssetManager()->useScript('webcomponent.field-media');
			Factory::getDocument()->getWebAssetManager()->useScript('webcomponent.field-user');
		}

		ob_start();
		?>

			<joomla-field-user class="field-user-wrapper"
					data-url="index.php?option=com_users&amp;view=users&amp;layout=modal&amp;tmpl=component&amp;required=0&amp;field={field-user-id}&amp;ismoo=0&amp;excluded=WyIiXQ=="
					data-modal=".modal"
					data-modal-width="100%"
					data-modal-height="400px"
					data-input=".field-user-input"
					data-input-name=".field-user-input-name"
					data-button-select=".button-select"
					url="index.php?option=com_users&view=users&layout=modal&tmpl=component&required=0&field=jform_created_by"
					modal=".modal"
					modal-width="100%"
					modal-height="400px"
					input=".field-user-input"
					input-name=".field-user-input-name"
					button-select=".button-select"
					>
						<div>
							<label for="userId" class="w-100"><?php echo JText::_('LNG_USERID')?></label>
							<div class="input-group flex-nowrap">
								<input
									type="text" id="jform_created_by"
									value="<?php echo $name ?>"
									placeholder="Select a User."
									readonly
									class="field-user-input-name form-control"/>
								<div class="input-group-append">
									<a class="btn btn-primary button-select" title="Select User"><span class="icon-user"></span></a>
								</div>
							</div>

							<?php if(JBusinessUtil::isJoomla3()){ ?>
								<div id="userModal_jform_created_by" tabindex="-1" class="modal hide fade">
									<div class="modal-header">
											<button type="button" class="close novalidate" data-dismiss="modal">�</button>
												<h3>Select User</h3>
											</div>
									<div class="modal-body">
										</div>
									<div class="modal-footer">
										<button class="btn" data-dismiss="modal">Cancel</button>
									</div>
								</div>
							<?php }else{ ?>
								<div id="userModal_jform_created_by" role="dialog" tabindex="-1" class="joomla-modal modal fade" data-url="index.php?option=com_users&view=users&layout=modal&tmpl=component&required=0&field=jform_created_by" data-iframe="&lt;iframe class=&quot;iframe&quot; src=&quot;index.php?option=com_users&amp;view=users&amp;layout=modal&amp;tmpl=component&amp;required=0&amp;field=jform_created_by&quot; name=&quot;Select User&quot; title=&quot;Select User&quot; height=&quot;100%&quot; width=&quot;100%&quot;&gt;&lt;/iframe&gt;">
									<div class="modal-dialog modal-lg jviewport-width80">
										<div class="modal-content">
											<div class="modal-header">
											<h3 class="modal-title">Select User</h3>
												<button type="button" class="btn-close novalidate" data-bs-dismiss="modal" aria-label="Close">
										</button>
									</div>
								<div class="modal-body jviewport-height60">
									</div>
								<div class="modal-footer">
									<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button></div>
										</div>
									</div>
								</div>
							<?php } ?>
						</div>
						<input type="hidden" id="jform_created_by_id" name="<?php echo $vName?>" value="<?php echo $userId ?>"  class="field-user-input " data-onchange=""/>
				</joomla-field-user>
		<?php
		//$content = ob_get_contents();
		//return $content;
	}

	/**
     * Check if there is no other trip booked at the same time for an user
     *
	 * @param $userId int id of user creating the booking
	 * @param $date string date of appointment
	 * @param $time string time of appointment
     */
	public static function checkTripBookingAvailability ($userId, $date, $orderId) {		
		$bookingsTable = JTable::getInstance("TripBookings", "JTable");
		$result = $bookingsTable->checkAvailability($userId, $date, $orderId);
		
		return $result;
	}

	public static function checkUserBookingCapability($userId = null) {
		
		JTable::addIncludePath(JPATH_ROOT.'/administrator/components/com_jbusinessdirectory/tables');
		$packagesTable = JTable::getInstance("Package", "JTable");
		$bookingsTable = JTable::getInstance("TripBookings", "JTable");

		if(!isset($userId)) {
			$userId = JBusinessUtil::getUser()->id;
		}

		$packages = $packagesTable->getUserActivePackages($userId);

		$tripsCount = 0;
		$startDates = array();		
		$endDates = array();		
		foreach($packages as $package) {
			if(in_array(TRIPS, $package->features)) {
				$tripsCount += $package->max_trips;
				$startDates[] =  $package->start_date;
				$endDates[] =  $package->end_date;
			}
		}

		usort($startDates, function($a, $b) {
			return strtotime($a) > strtotime($b);
		});
		usort($endDates, function($a, $b) {
			return strtotime($a) < strtotime($b);
		});
		
		$bookedTripsCount = 0;
		if(!empty($startDates) && !empty($endDates)) {
			$startDate = $startDates[0];
			$endDate = $endDates[0];
			$bookedTripsCount = $bookingsTable->getTotalBookedTrips($userId,$startDate, $endDate);
		}


		if($bookedTripsCount >= $tripsCount) {
			return false;
		}
		
		return true;
	}

	/**
	 * Get Trip Booking states
	 *
	 * @return array
	 *
	 * @since 5.7.0
	 */
	public static function getTripBookingStates() {
		$statuses      = array();
		$status        = new stdClass();
		$status->value = TRIP_BOOKING_CREATED;
		$status->text  = JText::_("LNG_CREATED");
		$statuses[]    = $status;
		$status        = new stdClass();
		$status->value = TRIP_BOOKING_CONFIRMED;
		$status->text  = JText::_("LNG_CONFIRMED");
		$statuses[]    = $status;
		$status        = new stdClass();
		$status->value = TRIP_BOOKING_CANCELED;
		$status->text  = JText::_("LNG_CANCELED");
		$statuses[]    = $status;

		return $statuses;
	}
}

/**
 * Utility function for displaying debug messages
 *
 */
if (!function_exists('dump')) {
	function dump() {
		$args = func_get_args();

		echo '<pre>';

		foreach ($args as $arg) {
			var_dump($arg);
		}
		echo '</pre>';
		//exit;
	}
}

/**
 * Utility function for displaying debug messages
 *
 */
if (!function_exists('dbg')) {
	function dbg($text) {
		echo "<pre>";
		var_dump($text);
		echo "</pre>";
	}
}