<?php
/**
 * The freelancer/members list for the UNI Theme. Old file in archive directory.
 *
 * Ionicware, INC 2018
 * 12/7/2018
 */
include_once('include/config.php');
include_once('include/functions/import.php');

/**
 * Redirect the user to the old version if not using the
 * new theme.
 */
if ($config['themeUni']	!= 1)
{
	include('archive/freelancers.php');
	die();
}

/**
 * Setup our sort and order by variables
 */
$sortBy['req'] 		= !empty($_REQUEST['sort']) ? cleanit($_REQUEST['sort']) : 'recommendations';
$sortBy['field'] 	= 'recommendations'; // Default
$filterBy['req']	= cleanit($_REQUEST['action']);
$filterBy['query']	= trim(strip_tags(cleanit($_REQUEST['query'])));

/**
 * If the query is full but not the req, we can assume it is
 * due to the search bar.
 */
if (!empty($filterBy['query']) && empty($filterBy['req']))
	$filterBy['req'] = 'search';

/**
 * We set our page title here because it changes below depending on the
 * options selected
 */
$config['pagetitle']		= $lang[1826];

/**
 * Determine how we are sorting
 */
if (empty($_REQUEST['order']) || $_REQUEST['order'] == 'desc') $sortBy['order'] = 'desc';
else $sortBy['order'] = 'asc';

/**
 * Determine what we are sorting by.
 */
switch ($sortBy['req'])
{
	case 'userlevel':
		$sortBy['field']		= 'userlevel';
		$requestString			.= 'sort=userlevel';
		$sortBy['order']		= 'desc';
		break;
	case 'response':
		$sortBy['field']		= 'average_response_time';
		$requestString			.= 'sort=response';
		$filterBy['condition']	= ' AND average_response_time > 0 ';
		$sortBy['order']		= 'asc';
		break;
	case 'rating':
		$sortBy['field']		= 'rating';
		$requestString			.= 'sort=rating';
		$filterBy['condition']	= ' AND rating > 0 ';
		$sortBy['order']		= 'desc';
		break;
	case 'username':
		$sortBy['field']		= 'username';
		$requestString			.= 'sort=username';
		$sortBy['order']		= 'asc';
		break;
	case 'lastlogin':
		$sortBy['field']		= 'lastlogin';
		$requestString			.= 'sort=lastlogin';
		$sortBy['order']		= 'desc';
		break;
	case 'join':
		$sortBy['field']		= 'addtime';
		$requestString			.= 'sort=join';
		$sortBy['order']		= 'desc';
		break;
	default:
		/**
		 * New marketplaces do not have any recommendations
		 * so we can't default to that.
		 *
		 * 2021-08-25 09:38:05 JD
		 */
		if ($config['isIonicware'])
		{
			$sortBy['req']			= 'recommendations';
			$sortBy['field']		= 'total_recommendations';
			$filterBy['condition']	= ' AND total_recommendations > 0 ';
		}
		else
		{
			$sortBy['req']			= 'join';
			$sortBy['field']		= 'addtime';
			$requestString			.= 'sort=join';
			$sortBy['order']		= 'desc';
		}
		$requestString			.= 'sort=default';
		$sortBy['order']		= 'desc';
		break;
}

/**
 * Add the sortng order to the request string
 */
if (!empty($requestString)) $requestString .= '&order=' . $sortBy['order'];

/**
 * These are our filtering options
 * The user is selecting only online users.
 */
if ($_REQUEST['onlinenow'] == 1)
{
	$filterBy['condition'] 	.= " AND lastlogin>UNIX_TIMESTAMP(NOW())-1800 "; // 30 min
	$requestString 			.= '&onlinenow=1';
}

/**
 * The user is filtering by user level
 */
if (!empty($_REQUEST['level']))
{
	foreach ($_REQUEST['level'] as $lvl)
	{
		if (intval($lvl) && intval($lvl) >= 1 && intval($lvl) <= 4)
		{
			if (intval($lvl) == 4)
				$levelString 	.= " userlevel >= '".escape($lvl)."' OR ";
			else
				$levelString 	.= " userlevel = '".escape($lvl)."' OR ";

			$levelCounter 	= $levelCounter + intval($lvl);
			$requestString 	.= '&level[]=' . intval($lvl);
		}
	}

	if (!empty($levelString) && $levelCounter != 10) // 10 means they selected all levels
	{
		if (substr($levelString, -3) == 'OR ')
			$levelString = substr($levelString, 0, -3);

		$filterBy['condition']	.= " AND ({$levelString})";
	}
}

/**
 * Average response time
 */
if (!empty($_REQUEST['avgrestime']) && is_string($_REQUEST['avgrestime']) && stristr($_REQUEST['avgrestime'], ',')) // ?avgrestime[]= skipped here on 7.4 too
{
	$rangeArray = explode(',', $_REQUEST['avgrestime']);

	/*
		* Convert these into seconds
		*/
	$minSeconds = legacyNumber($rangeArray[0]) * 3600; // the URL's text read as 7.4 did: 8 throws on ?avgrestime=a,b
	$maxSeconds = legacyNumber($rangeArray[1]) * 3600;

	/**
	 * Check to make sure the range is withing acceptable params
	 */
	if (intval($rangeArray[0]) > 1 || intval($rangeArray[1]) < 100)
	{
		/**
		 * Make sure we only show people who have a response time
		 */
		$filterBy['condition']	= ' AND average_response_time > 0 ';

		/**
		 * Determine what to show/do
		 */
		if (intval($rangeArray[1]) == 100)
			$filterBy['condition'] .= " AND average_response_time >= '" . escape(intval($minSeconds)) . "'";
		else if (intval($rangeArray[0]) == 1)
			$filterBy['condition'] .= " AND average_response_time <= '" . escape(intval($maxSeconds)) . "'";
		else
			$filterBy['condition'] .= " AND average_response_time BETWEEN '" . escape(intval($minSeconds))."' AND '".escape(intval($maxSeconds)) . "'";

		$requestString 	.= '&avgrestime=' . strip_tags(cleanit($_REQUEST['avgrestime']));
	}
}

if (!empty($filterBy['req']) && !empty($filterBy['query']))
{
	switch ($filterBy['req'])
	{
		case 'skill':
			$filterBy['condition']	.= " AND (skills LIKE '%" . escape($filterBy['query']) . "%') ";
			$config['pagetitle']  	= $config['pagetitle'] . ' ' . $lang[414] . ' ' . $lang[2454] . ' ' . $filterBy['query'];
			$requestString 			.= '&action=' . $filterBy['req'] . '&query=' . $filterBy['query'];
			break;
		case 'search':
			$filterBy['condition'] .= " AND (
												description LIKE '%" . escape($filterBy['query']) . "%'
												OR username LIKE '%" . escape($filterBy['query']) . "%'
											)";
			$config['pagetitle']  	= $config['pagetitle'] . ' ' . $lang[414] . ' ' . $skill;
			$requestString 	.= '&action=' . $filterBy['req'] . '&query=' . $filterBy['query'];
			break;
		default:
			$filterBy['req'] 	= null;
			$filterBy['query'] 	= null;
		break;
	}
}

/*
 * The two queries to count and fetch all
 * users.
 * 9/15/2013
 */
$countQuery 	= "SELECT count(USERID) AS total
					FROM members
					WHERE show_freelancer = 1
					AND status = 1
					" . $filterBy['condition'];
// $results		= $conn->CacheExecute(500, $countQuery);
// $totalResults	= $results->fields['total'];
$results		= queryCache($countQuery, 3600, true);
$totalResults	= $results['total'];

/*
 * Every profile skill links /freelancers/skill/{skill}; most match nobody and
 * Google calls the empty list a soft 404. Keep empty skill lists and free-text
 * searches out of the index.
 * 2026-09-23
 */
if (($filterBy['req'] == 'skill' && intval($totalResults) == 0) || $filterBy['req'] == 'search') $config['noindex'] = 1;

/**
 * Fetch our page data
 */
$pageData = fetchCurrentPageData($totalResults, 'page');

/**
 * Name the columns rather than SELECT *.
 *
 * members averages 2.6KB a row, and this page sorts over roughly 1.5 million of
 * them, so a deep page was reading hundreds of megabytes to show forty people.
 * The list below is everything the loop under this query and
 * views/view_freelancers-listings.php actually read, plus profile_data, which
 * getUserBackground() takes off the row to avoid a query per freelancer.
 *
 * members.vetted_human is seoclerks only (issue #1264), and naming an absent
 * column is a fatal "Unknown column" rather than the silent omission SELECT *
 * gave us - so it is gated the same way ajax.php gates it. The view reads it
 * through isset(), so the sister storefronts still render without it.
 *
 * members.vetted is on every live storefront. The one exception, monsterbacklinks,
 * is retired and is not kept updated, so it is not worth a flag of its own.
 *
 * 2026-10-07 JD
 */
$freelancerColumns = 'USERID, username, userlevel, rating, profilepicture, profile_data,'
					. ' addtime, lastlogin, description, skills, ip, lip,'
					. ' average_response_time, total_recommendations, vetted';

if (!empty($config['isSeoClerksBrand']))		$freelancerColumns .= ', vetted_human';

$query 		= "SELECT " . $freelancerColumns . "
				FROM members
				WHERE show_freelancer = 1
				AND status = 1
				" . $filterBy['condition'] . "
				ORDER BY " . $sortBy['field'] . " " . $sortBy['order'] . "
				LIMIT " . intval($pageData['start']) . ',' . intval($config['items_per_page'])
				;
$results		= $conn->CacheExecute(500, $query);
$freelancers	= $results->getrows();


foreach ($freelancers as &$user)
{
	/*
	* Get the last login date in days for the gig
	* 8/5/2012
	*/
	$user['lastLoginDays'] 		= GetUserLastLoginDays($user['USERID'], $user['lastlogin']);

	/*
	* Get the country code
	* 5/20/2021
	*/
	$user['countryReg']			= GetCountryCode($user['ip']);

	/*
	* Get the totals for the user
	* 8/5/2012
	*/
	$user['ratingData'] 		= GetBuyerRatingsTotal($user['USERID']);

	/*
	* Get the country code
	* 6/28/2012
	*/
	$user['countryReg']			= GetCountryCode($user['ip']);
	$user['countryLast']		= GetCountryCode($user['lip']);

	/*
	* Make the description look decent
	* 9/15/2013
	*/
	$user['description'] 		= RemoveTextBbcode($user['description']);
	$user['description'] 		= str_ireplace(PHP_EOL, ' ', $user['description']);
	$user['description'] 		= ReplaceDescriptionCharacters($user['description']);

	/*
	* How quickly does this
	* user respond
	* 9/15/2013
	*/
	$user['average_response_time'] = GetResponseTime($user['average_response_time'], true);

	/*
	* Get the user skills and explode them.
	* 1/12/2013
	*/
	if (!empty($user['skills']))
	{
		$user['skills'] 	= str_ireplace(',', ' ', $user['skills']);
		$skills 			= explode(' ', $user['skills']);

		/**
		 * Loop through the skills and count the results, stopping at 5
		 */
		$skillCount = 0;
		foreach ($skills as $skill)
		{
			if (!empty($skill) && strlen($skill) <= 15 && strlen($skill) > 2 && $skillCount <= 5)
			{
				$user['skillsdisplaynew'] .= "<a class='tag' href='" . $config['baseurl'] . "/freelancers/skill/" . $skill . "'>" . $skill . "</a>";
				$skillCount++;
			}
		}

		$user['skills'] 	= str_ireplace(' ', ', ', $user['skills']);
		$user['skills'] 	= str_ireplace(',,', ', ', $user['skills']);
		$user['showskills'] = 1;

		/*
		* Replace the last , if there is one
		* 7/5/2016
		*/
		if (substr($user['skillsdisplay'], -2) == ', ')
		{
			$user['skillsdisplay'] = substr($user['skillsdisplay'], 0, -2);
		}
	}
	else $user['showskills'] = 0;

	/*
	* Is the User online?
	* 12/28/2012
	*/
	if (IsUserOnline($user['USERID'], $user['lastlogin']))
		$user['online'] = 1;
	else
		$user['online'] = 0;

	/*
	* Replace 4 with X
	*/
	$user['userlevel'] = getUserLevelFromLevel($user['userlevel']);

	/**
	 * Code replaced with the background function.
	 *
	 * 2023-05-02 09:39:12 JD
	 */
	$user['backgroundPic']	= getUserBackground($user['USERID'], '', false, $user);
} // End foreach

/*
 * Pagination, refactored to a function 08/21/2018
 * Note: function still looks like ass.
 *
 * Returns an array of values.
 */
$linkUrl 	= $config['baseurl'] . '/freelancers/sort/' . $sortBy['req'] . '/' . $sortBy['order'] . '/page/';

// Create the pagination
$paginationArray = createPagination($pageData['start'] + 1, $pageData['total'], $pageData['page'], $pageData['lastPage'], $linkUrl, '', 10, "ajaxTableSort no-args", "data-droplet='freelancers'", true, false, true);

// Set the array results to local values
$pageShowingUni = $paginationArray['pageShowingUni'];
$pagetoplinks	= $paginationArray['pagetoplinks'];
$pagelinks		= $paginationArray['pagelinks'];
$pageNext		= $paginationArray['pageNext'];
$pagelinksUni	= $paginationArray['pagelinksUni'];

/*
* Set the header category
* 10/10/2018
*/
$ajax 						= intval($_REQUEST['ajax']);
$CSFR 						= GenerateCSFRCode();
$header_sub_cat_active 		= 'freelancers';
$header_cat_active 			= 'community';

$customModalData['successMessage']	= $lang[3472];

/*
* Include templates that we need, called in the footer-loader.php file.
*/
$__includeTemplates[1]['path']	= $config['basedir']  . '/views/js/autocomplete/__view-single.js.html';

$customModalData['type'] 				= 'user';

/**
 * Include the language that we will need
 */
$config['include']['footerJs'] .= getLanguageForJS(array(3472, 3488, 2766, 3777, 3792, 3793));

$config['include']['modals'][0] 		= 'views/modal/view_modal-message-droplet.php';
$config['include']['modals'][1] 		= 'views/modal/view_modal-custom-order-droplet.php';
$config['include']['wysibb']			= 1;
$config['include']['includeUploadJs'] 	= 1;

if (userNeedsCaptcha())
{
	$config['set_recaptcha'] 				= 1;
}

/*
* Create a new JWT for sockets.io
* 10/31/2018
*/
$__socketParams = array(
	"type" => "freelancers",
	"acc" => array(),
	"ouid" => array_column($freelancers, 'USERID')
);

if ($_REQUEST['rootLink'] == 1)
{
	include 'views/view_freelancers.php';
	die();
}

if ($ajax == 1)
{
	$firstLoad = 0;

	/**
	 * Replaced the code below with this as the code below was
	 * redundant in multiple files.
	 * 12/4/2018
	 */
	$ajaxJs = paginationFooterAjax($pagelinksUni, $pageShowingUni, $pageNext, $pageData);

	include 'views/view_freelancers-listings.php';
	die();
}
else
{
	/*
	 * Include templates that we need, called in the footer-loader.php file.
	 */
	$__includeTemplates[0]['path']	= $config['basedir']  . '/views/js/autocomplete/__view-marketplace.js.html';

	include 'views/header/view_header-loader.php';
	include 'views/view_freelancers.php';
	include 'views/footer/view_footer-loader.php';
}