/** * Возвращает страницу каталога фрилансеров со всеми необходимыми причиндалами. * * Немного оптимизированная замена old_getCatalog * - оптимизированы запросы, убран устаревший функционал * - отключен фильтр кроме категорий но поддерка остается (на поиск работает сфинкс) * - без фильтра полностью закешировал выдачу * * * @param integer prof_id ид. профессии (раздела каталога). Если 0, то выводим фрилансеров из общего каталога. * @param integer uid ид. юзера, просматривающего каталог. * @param integer count количество всего фрилансеров в данном разделе каталога. * @param integer size количество фрилансеров на данной странице каталога. * @param array works массив, индексированный ид. фрилансеров, содержащий массив из трех первых работ данного фрилансера в данном разделе. * @param integer limit сколько фрилансеров на одной странице. * @param integer offset OFFSET. * @param string order тип сортировки (см. использование). * @param int direction порядок сортировки. 0 -- по убывающей, не 0 -- по возрастающей. * @param int favorite флаг -- показывать ли только избранных. * @param array filter массив с параметрами фильтра или NULL -- фильтр не применен. * * @return array массив с фрилансерами. */ function new_getCatalog($prof_id, $uid, &$count, &$size, &$works, $limit, $offset, $order = "general", $direction = 0, $favorite = 0, $filter = NULL) { require_once $_SERVER['DOCUMENT_ROOT'] . "/classes/projects.php"; global $DB; //текущая группа или специализация $current_categoty_id = 0; //группа или специализация $current_categoty_is_spec = $prof_id > 0; $project_exRates = project_exrates::GetAll(); $fu_table = self::$fu_table; //Сбрасываем все параметры фильра кроме категории //так как эта выборка не поддерживает фильтр //фильтр осуществляется средствами поиска (сфинкс)! if (isset($filter['prof'])) { $tmp_filter = $filter; $filter = array(); $filter['prof'] = $tmp_filter['prof']; } $fprms = self::createCatalogFilterSql($filter, $prof_id); if ($fprms == -1) { return null; } //@todo: фильтр каталога более не используем но поддержку оставляем //$filter_join не используется! //$filter_where только по разделам list($filter_where, $filter_join) = $fprms; $filter_join = ''; if ($filter_where) { $filter_where = ' AND ' . $filter_where; } $size = 0; if ($prof_id) { $or_prof = professions::GetProfessionOrigin($prof_id); $ord_spec = ', s.its_his_main_spec DESC'; } // Список специализаций для фильтрации в портфолио $specs_list = ''; $dir_sql = !$direction ? 'DESC' : 'ASC'; switch ($order) { case "opinions": $uc_side = 'INNER'; $order = ", osum {$dir_sql}, s.rating {$dir_sql}"; break; case "sbr": $uc_side = 'INNER'; $order = ", ssum {$dir_sql}, s.rating {$dir_sql}"; break; case "cost_hour": $order = "{$ord_spec}, cost_hour_is_0, cost_fm {$dir_sql}, s.rating {$dir_sql}"; $orderCf = 'pc.cost_hour'; $orderCt = 'pc.cost_type_hour'; break; case "cost_month": $order = "{$ord_spec}, COALESCE(s.cost_month,0)=0, cost_fm {$dir_sql}, s.rating {$dir_sql}"; $orderCf = 's.cost_month'; $orderCt = 's.cost_type_month'; break; case "cost_proj": $order = "{$ord_spec}, COALESCE(cost_from,0)=0, cost_fm {$dir_sql}, s.rating {$dir_sql}"; $orderCf = 'pc.cost_from'; $orderCt = 'pc.cost_type'; break; case "cost_1000": $order = "{$ord_spec}, COALESCE(cost_1000,0)=0, cost_fm {$dir_sql}, s.rating {$dir_sql}"; $orderCf = 'pc.cost_1000'; $orderCt = 'pc.cost_type'; break; case "general": default: $order = "{$ord_spec}, rating_get(s.rating, s.is_pro, s.is_verify, s.is_profi) {$dir_sql}"; break; } $cost_fm = ''; if (isset($orderCf, $orderCt)) { $cost_fm = ",\n CASE WHEN COALESCE({$orderCt},0) = 0 THEN {$orderCf} * {$project_exRates[24]}\n WHEN {$orderCt} = 1 THEN {$orderCf} * {$project_exRates[34]}\n WHEN {$orderCt} = 2 THEN {$orderCf} * {$project_exRates[44]}\n WHEN {$orderCt} = 3 THEN {$orderCf} * {$project_exRates[14]}\n ELSE {$orderCf}\n END as cost_fm "; } if (!isset($uc_side)) { //@todo: фильтр каталога более не используем но поддержку оставляем $uc_side = strpos($filter_where, 'uc.') !== false ? 'INNER' : 'OUTER'; } $uc_cols = $uc_join = array('INNER' => '', 'OUTER' => ''); //В зависимости наличия сортировки выборка и обьединение включается до лимита или после $uc_cols[$uc_side] = ", \n uc.ops_emp_plus + uc.ops_frl_plus as sg, \n uc.ops_emp_minus + uc.ops_frl_minus as sl, \n uc.ops_emp_null + uc.ops_frl_null as se,\n zin(uc.paid_advices_cnt + uc.sbr_opi_plus + uc.tu_orders_plus + uc.projects_fb_plus)-zin(uc.sbr_opi_minus + uc.tu_orders_minus + uc.projects_fb_minus) as ssum, \n zin(uc.ops_emp_plus)-zin(uc.ops_emp_minus) as osum,\n (uc.paid_advices_cnt + uc.sbr_opi_plus + uc.tu_orders_plus + uc.projects_fb_plus) AS total_opi_plus,\n (uc.sbr_opi_null) AS total_opi_null,\n (uc.sbr_opi_minus + uc.tu_orders_minus + uc.projects_fb_minus) AS total_opi_minus,\n uc.*"; $uc_join[$uc_side] = "LEFT JOIN users_counters uc ON uc.user_id = s.uid"; //В наружнем запросе испозьзуются поля из user_counters, поэтому JOIN нужно делать всегда $uc_join['OUTER'] = "LEFT JOIN users_counters uc ON uc.user_id = s.uid"; if ($prof_id) { // находимся в конкретном разделе (нижний уровень, подраздел). $current_categoty_id = $or_prof; //Если есть сортировки или фильтр то включаем внутрь выборки //@todo: фильтр в каталога не используется но поддержку оставляем $pc_side = strpos($filter_where, 'pc.') !== false || strpos($cost_fm, 'pc.') !== false ? 'INNER' : 'OUTER'; $pc_cols = $pc_join = array('INNER' => '', 'OUTER' => ''); //В зависимости наличия сортировки выборка и обьединение включается до лимита или после $pc_cols[$pc_side] = ", \n (COALESCE(pc.cost_hour, 0) = 0) as cost_hour_is_0, \n pc.cost_hour, \n pc.cost_type_hour, \n pc.cost_from, \n pc.cost_type, \n pc.cost_1000"; $pc_join[$pc_side] = "LEFT JOIN portf_choise pc ON pc.prof_id = '{$or_prof}' AND pc.user_id = s.uid"; //Основная выборка $fu = "(\n SELECT \n s.*, \n true AS its_his_main_spec \n FROM {$fu_table} AS s\n WHERE spec_orig = '{$or_prof}'\n \n UNION ALL\n \n SELECT \n s.*, \n false AS its_his_main_spec \n FROM {$fu_table} AS s\n INNER JOIN spec_add_choise sp ON sp.user_id = s.uid AND sp.prof_id = '{$or_prof}' \n WHERE s.is_pro = true \n )"; //Собираем общий запрос //@todo: Рекомендуется вынести completed_cnt в users_counters таблицу и с ней соединяться //тем более, что в ней уже есть кол-во по новой БС reserves_completed_cnt //нужно добавить поле по старой БС и пересчитать туда $sql = "\n SELECT s.*,\n city.city_name as str_city, \n country.country_name as str_country, \n COALESCE(smeta.completed_cnt, 0) + COALESCE(uc.reserves_completed_cnt, 0) AS completed_cnt, -- старые БС + новые БС\n rating_get(s.rating, s.is_pro, s.is_verify, s.is_profi) as t_rating\n {$uc_cols['OUTER']}\n {$pc_cols['OUTER']}\n FROM (\n SELECT s.* \n {$cost_fm}, \n s.cost_hour as frl_cost_hour, \n s.cost_type_hour as frl_cost_type_hour,\n \n (fb.id > 0)::boolean AS is_binded,\n fb.id AS fb_id,\n fb.date_start AS fb_date_start \n \n {$uc_cols['INNER']}\n {$pc_cols['INNER']}\n FROM {$fu} AS s \n {$uc_join['INNER']}\n {$pc_join['INNER']}\n {$filter_join}\n LEFT JOIN freelancer_binds fb \n ON fb.user_id = s.uid \n AND fb.prof_id = '{$or_prof}' \n AND fb.status = true \n AND fb.date_stop > NOW() --желательно сделать индекс с условием\n WHERE \n s.is_banned = '0' \n AND s.last_time > now() - '6 months'::interval \n AND ( s.cat_show = 't' OR s.is_pro = 'f' ) --желательно исправить во вьюшке\n {$filter_where} \n ORDER BY (fb.id IS NULL)::boolean ASC, fb.date_start DESC, s.is_pro DESC {$order}, s.uid\n LIMIT {$limit} OFFSET {$offset} \n ) as s \n {$uc_join['OUTER']}\n {$pc_join['OUTER']}\n LEFT JOIN country ON country.id = s.country\n LEFT JOIN city ON city.id = s.city\n LEFT JOIN sbr_meta AS smeta ON smeta.user_id = s.uid -- старые БС\n ORDER BY (fb_id IS NULL)::boolean ASC, fb_date_start DESC, s.is_pro DESC {$order}, s.uid\n "; //Счетчик количества $countSql = "\n SELECT \n COUNT(s.uid) AS count, \n SUM(s.is_pro::int) AS payed \n FROM {$fu} AS s {$filter_join} " . ($filter_where ? $uc_join['INNER'] . ' ' . $pc_join['INNER'] : '') . " WHERE \n s.is_banned = '0' \n AND ( s.cat_show = 't' OR s.is_pro = 'f' ) --желательно исправить во вьюшке\n AND s.last_time > now() - '6 months'::interval \n {$filter_where}"; } else { $join_add_spec = ''; $prof_choise_condition = "pc.prof_id = s.spec_orig"; $pattern = "#(s.spec_orig\\s+(IN\\s+\\([\\d,]+\\)))#"; $order_add_spec = ""; $order_add_spec_field = ""; if (preg_match($pattern, $filter_where, $m)) { $filter_where = preg_replace($pattern, "(\$1 OR (sa.prof_id \$2 AND s.is_pro = 't' ))", $filter_where); $join_add_spec = "LEFT JOIN \n spec_add_choise sa\n ON sa.user_id = s.uid"; $prof_choise_condition = "(\n pc.prof_id = s.spec_orig\n OR pc.prof_id = sa.prof_id\n )"; //$order_add_spec = "aso DESC, "; $order_add_spec_field = "CAST(s.spec_orig {$m[2]} AS integer) AS aso, "; } // Сортировка фрилансеров внутри специализаии верхнего уровня по подуровням $spec_case_order = ''; if (isset($m[2]) && $m[2]) { $spec_case_order = ", CASE WHEN s.spec_orig {$m[2]} THEN 1 ELSE 2 END"; $specs_list = "p.prof_id {$m[2]}"; } // Категория для закрепленной позиции $fb_on_prof = 0; if ($filter['prof']) { if (count($filter['prof'][0]) > 0) { $group_ids = array_keys($filter['prof'][0]); $fb_on_prof = $group_ids[0]; $current_categoty_id = $fb_on_prof; } } $sql = "\n SELECT\n s.*,\n city.city_name as str_city, \n country.country_name as str_country, \n COALESCE(smeta.completed_cnt, 0) + COALESCE(uc.reserves_completed_cnt, 0) AS completed_cnt, -- старые БС + новые БС\n p.name as profname, \n p.is_text,\n rating_get(s.rating, s.is_pro, s.is_verify, s.is_profi) as t_rating\n \n {$uc_cols['OUTER']}\n FROM (\n SELECT *\n FROM (\n SELECT \n DISTINCT ON (s.uid) \n s.*, \n s.cost_hour as frl_cost_hour, \n s.cost_type_hour as frl_cost_type_hour, \n {$order_add_spec_field} \n\n (COALESCE(pc.cost_hour, 0) = 0) as cost_hour_is_0, \n pc.cost_hour, \n pc.cost_from, \n pc.cost_type, \n pc.cost_1000, \n pc.cost_type_hour, \n \n (fb.id > 0)::boolean as is_binded, \n fb.id AS fb_id,\n fb.date_start AS fb_date_start\n \n {$cost_fm}\n {$uc_cols['INNER']}\n FROM {$fu_table} s \n {$join_add_spec} \n {$uc_join['INNER']}\n LEFT JOIN portf_choise pc \n ON {$prof_choise_condition} \n AND pc.user_id = s.uid \n LEFT JOIN freelancer_binds fb \n ON fb.user_id = s.uid \n AND fb.prof_id = {$fb_on_prof} \n AND fb.is_spec = FALSE\n AND fb.status = TRUE \n AND fb.date_stop > NOW() --желательно сделать индекс с условием\n {$filter_join}\n WHERE s.is_banned = '0' {$filter_where} \n AND ( s.cat_show = 't' OR s.is_pro = 'f' ) --желательно исправить во вьюшке\n AND s.last_time > now() - '6 months'::interval\n ) AS s \n ORDER BY \n (fb_id IS NULL)::boolean ASC, fb_date_start DESC, \n s.is_pro DESC {$spec_case_order} {$order}, {$order_add_spec} s.uid\n LIMIT {$limit} OFFSET {$offset}\n ) AS s\n {$uc_join['OUTER']}\n LEFT JOIN professions p ON p.id = s.spec \n LEFT JOIN country ON country.id = s.country \n LEFT JOIN sbr_meta AS smeta ON smeta.user_id = s.uid --старая БС\n LEFT JOIN city ON city.id = s.city\n ORDER BY\n (fb_id IS NULL)::boolean ASC, fb_date_start DESC, \n s.is_pro DESC {$spec_case_order} {$order}, {$order_add_spec} s.uid"; $filter_where .= " AND s.last_time > now() - '6 months'::interval AND ( s.cat_show = 't' OR s.is_pro = 'f' )"; $countSql = self::_createMainCountSql($filter_where, $filter_join, $join_add_spec); } $memBuff = new memBuff(); //$DB->setTimeout(90); $frls = $memBuff->getSql($error, $sql, self::CATALOG_MEM_LIFE, true, static::getCatalogMemTags($current_categoty_id, $current_categoty_is_spec)); //@todo: корректно сбрасывать установкой -1 //$DB->setTimeout(-1); if ($error || !$frls) { return NULL; } if (!$prof_id && !$offset && !$memBuff->getBWasMqUsed()) { professions::RecalcCatalogPositions(); } //$DB->setTimeout(90); $count_arr = $memBuff->getSql($error, $countSql, self::CATALOG_MEM_LIFE, true, static::getCatalogMemTags($current_categoty_id, $current_categoty_is_spec)); //$DB->setTimeout(); $count = $count_arr[0]['count']; $size = sizeof($frls); /* * @todo: судя по коду из оригинального getCatalog это не используется if ($prof_id && !$memBuff->getBWasMqUsed() && !$filter_where) { professions::UpdateProfessionCount($or_prof, $count, $count_arr[0]['payed']); } */ $frl_ids = array(); $frl_ids_map = array(); $tu_frl_ids = array(); foreach ($frls as $key => $row) { $frl_ids[$key] = $row['uid']; $frl_ids_map[$row['uid']] = $key; //Если вкладка ТУ выключена то сразу исключаем такие UID if (substr($row['tabs'], 7, 1) == 1) { $tu_frl_ids[$key] = $row['uid']; } } //Получение пользовательский превью работ/услуг require_once ABS_PATH . '/freelancers/widgets/FreelancersPreviewWidget.php'; require_once ABS_PATH . '/freelancers/models/FreelancersPreviewModel.php'; $freelancersPreviewModel = new FreelancersPreviewModel(); $list = $freelancersPreviewModel->getListByUids($frl_ids, $current_categoty_is_spec ? 0 : $current_categoty_id, $prof_id); $tmp_tu_uids = $tu_frl_ids; foreach ($list as $item) { //Если отключена вкладка ТУ то их исключаем if (!$item || $item->type == FreelancersPreviewModel::TYPE_TU && !in_array($item->user_id, $tmp_tu_uids)) { continue; } //Инициализируем данные юзера в работе/услуге пока только логин нужен $key = $frl_ids_map[$item->user_id]; $item->setUser(array('login' => $frls[$key]['login'])); //Инитим виджет если его нет if (!isset($frls[$key]['preview'])) { $frls[$key]['preview'] = new FreelancersPreviewWidget(array('is_owner' => $frls[$key]['uid'] == $uid && $frls[$key]['is_pro'] == 't')); } //Добавляем работу в виджет $frls[$key]['preview']->addItem($item); //Исключаем из дальнейшей обработки unset($frl_ids[$key], $tu_frl_ids[$key]); } if ($frl_ids) { $join_blocked = ' LEFT JOIN portfolio_blocked pb ON p.id = pb.src_id '; $where_blocked = ' AND pb.src_id IS NULL '; $sql = "\n SELECT \n p.id, \n p.user_id, \n p.name, \n p.descr, \n p.pict, \n p.prev_pict, \n p.show_preview, \n p.norder, \n p.prev_type, \n p.is_video\n FROM portfolio p \n INNER JOIN portf_choise pc ON pc.user_id = p.user_id AND pc.prof_id = p.prof_id \n " . ($prof_id ? '' : 'INNER JOIN freelancer f ON f.uid = p.user_id') . "\n {$join_blocked} \n WHERE p.user_id IN (" . implode(',', $frl_ids) . ")"; if ($specs_list) { $sql .= " AND {$specs_list}"; } else { $sql .= " AND p.prof_id = " . ($prof_id ? "'{$or_prof}'" : 'f.spec_orig'); } $sql .= " AND p.first3 = true {$where_blocked} ORDER BY p.user_id, p.norder"; if ($ret = $memBuff->getSql($error, $sql, self::CATALOG_PORTFOLIO_MEM_LIFE, true, static::getCatalogMemTags($current_categoty_id, $current_categoty_is_spec))) { $current_user_pf_ids = array(); foreach ($ret as $row) { $works[$row['user_id']][] = $row; if ($row['user_id'] == $uid) { $current_user_pf_ids[] = $row['id']; } } if (!empty($current_user_pf_ids)) { FreelancersPreviewModel::setExistPreviewData(FreelancersPreviewModel::TYPE_PF, $current_user_pf_ids); } } } //---------------------------------------------------------------------- //Если у пользователя не отображатся портфолио //то можно показать 3 последнии ТУ $exist_uids = $works ? array_keys($works) : array(); $tu_uids = array_diff($tu_frl_ids, $exist_uids); if ($tu_uids) { require_once ABS_PATH . '/tu/models/TServiceModel.php'; $tserviceModel = new TServiceModel(); if ($list = $tserviceModel->getListByUids($tu_uids, 3, self::CATALOG_PORTFOLIO_MEM_LIFE)) { $current_user_tu_ids = array(); foreach ($list as $item) { $key = $frl_ids_map[$item['user_id']]; $item['login'] = $frls[$key]['login']; $frls[$key]['tservices'][] = $item; if ($item['user_id'] == $uid) { $current_user_tu_ids[] = $item['id']; } } if (!empty($current_user_tu_ids)) { FreelancersPreviewModel::setExistPreviewData(FreelancersPreviewModel::TYPE_TU, $current_user_tu_ids); } } } return $frls; }
function setResults() { global $DB; require_once $_SERVER['DOCUMENT_ROOT'] . "/classes/freelancer.php"; if ($filter = $this->isAdvanced()) { foreach ($this->matches as $val) { $frl_ids[] = $val; } $page = $this->_advanced_page; $limit = $this->_advanced_limit; $offset = 0; if ($page > 0) { $offset = ($page - 1) * $limit; } $this->_offset = $offset; //if(isset($filter['nt_negative'])) $filter['not_negative'] = $filter['nt_negative']; $prof_id = is_array($filter['prof'][1]) ? array_keys($filter['prof'][1]) : array(); $order_by_spec_orign = ""; if (count($prof_id)) { $order_by_spec_orign = "s.spec IN (" . join(", ", $prof_id) . ") DESC,"; } $prof = $filter['prof']; unset($filter['prof']); $fprms = freelancer::createCatalogFilterSql($filter, 0); $filter_sql = $inner_sql = ''; if ($fprms !== -1) { list($filter_sql, $inner_sql) = $fprms; if ($filter_sql) { $filter_sql = ' AND ' . $filter_sql; } } $sql = "SELECT \n COUNT(u.uid) as cnt \n FROM users u\n LEFT JOIN \n freelancer s ON s.uid = u.uid\n LEFT JOIN\n portf_choise pc ON ( pc.prof_id = s.spec_orig AND pc.user_id = s.uid )\n LEFT JOIN\n users_counters uc ON ( uc.user_id = u.uid )\n {$inner_sql} \n WHERE \n u.uid IN (" . implode(", ", $frl_ids) . ") \n AND \n u.is_banned = '0'\n {$filter_sql} \n LIMIT 1;"; $this->total = $DB->val($sql); $sql = "SELECT \n u.uid as uid, \n u.photo, \n u.role, \n u.is_pro, \n u.is_profi,\n u.is_team, \n u.is_pro_test, \n u.info_for_reg, \n p.name as name_prof, \n u.login, \n u.uname, \n u.usurname,\n u.email, \n u.skype, \n s.site, \n ctr.country_name, \n ct.city_name, \n s.spec_text, \n s.resume, \n s.konk, \n s.blocks, \n s.status_type, \n s.cost_month, \n s.cost_hour AS frl_cost_hour, \n s.cost_type_hour as frl_cost_type_hour,\n s.in_office, \n s.exp, \n s.tabs,\n \n uc.sbr_opi_plus, \n uc.sbr_opi_minus, \n uc.sbr_opi_null,\n \n pc.cost_from, \n pc.cost_to, \n pc.cost_1000, \n pc.cost_type, \n uc.ops_emp_null + uc.ops_frl_null AS se, \n uc.ops_emp_plus + uc.ops_frl_plus AS sg, \n uc.ops_emp_minus + uc.ops_frl_minus AS sl, \n s.cost_type_hour, \n s.cost_type_month, \n rating_get(s.rating, s.is_pro, s.is_verify, s.is_profi) as t_rating,\n (add_spec.additional_specs || ', ' || COALESCE(p_spec.paid_specs, '')) AS additional_specs,\n -- get_additional_specs_as_string(u.uid) AS additional_spec,\n \n (uc.paid_advices_cnt + uc.sbr_opi_plus + uc.tu_orders_plus + uc.projects_fb_plus) AS total_opi_plus,\n (uc.sbr_opi_null) AS total_opi_null,\n (uc.sbr_opi_minus + uc.tu_orders_minus + uc.projects_fb_minus) AS total_opi_minus,\n \n COALESCE(smeta.completed_cnt, 0) + COALESCE(uc.reserves_completed_cnt, 0) AS completed_cnt -- старые БС + новые БС\n \n FROM users u\n LEFT JOIN freelancer s ON s.uid = u.uid\n LEFT JOIN portf_choise pc ON ( pc.prof_id = s.spec_orig AND pc.user_id = s.uid )\n LEFT JOIN professions p ON p.id = s.spec AND p.id > 0\n LEFT JOIN users_counters uc ON uc.user_id = u.uid\n LEFT JOIN country ctr ON ctr.id = s.country AND ctr.id > 0\n LEFT JOIN city ct ON ct.id = s.city AND ct.id > 0\n LEFT JOIN sbr_meta AS smeta ON smeta.user_id = u.uid -- старые БС\n LEFT JOIN \n ( \n SELECT \n array_to_string(array_agg(p.name), ', '::text) AS additional_specs, \n sa.user_id AS uid\n FROM spec_add_choise AS sa\n LEFT JOIN professions AS p ON p.id = prof_id\n\t GROUP BY sa.user_id\n ) AS add_spec ON add_spec.uid = u.uid\n LEFT JOIN \n ( \n SELECT \n array_to_string(array_agg(p.name), ', '::text) AS paid_specs, \n sp.user_id AS uid\n FROM spec_paid_choise AS sp\n LEFT JOIN professions AS p ON p.id = prof_id\n\t GROUP BY sp.user_id\n ) AS p_spec ON p_spec.uid = u.uid \n \n {$inner_sql}\n WHERE\n u.uid IN (" . implode(", ", $frl_ids) . ") AND \n u.is_banned = '0' \n {$filter_sql}\n ORDER BY u.is_pro DESC, {$order_by_spec_orign} s.rating DESC, u.uid \n LIMIT {$limit} OFFSET {$offset}"; //echo "<pre>".$sql; $this->results = $DB->rows($sql); } else { $this->results = $this->getRecords('is_pro DESC, rating DESC, id'); } if ($this->results) { $frl_ids_map = array(); $tu_frl_ids = array(); foreach ($this->results as $key => $row) { $frl_ids[] = $row['uid']; $frl_ids_map[$row['uid']] = $key; //Если вкладка ТУ выключена то сразу исключаем такие UID if (substr($row['tabs'], 7, 1) == 1) { $tu_frl_ids[$key] = $row['uid']; } } $uid = isset($_SESSION["uid"]) ? $_SESSION["uid"] : 0; $is_spec = isset($prof[0]); $categoty_id = $is_spec ? key($prof[0]) : 0; $prof_id = !$is_spec && isset($prof[1]) ? key($prof[1]) : 0; //print_r($current_categoty_id); //exit; //Получение пользовательский превью работ/услуг require_once ABS_PATH . '/freelancers/widgets/FreelancersPreviewWidget.php'; require_once ABS_PATH . '/freelancers/models/FreelancersPreviewModel.php'; $freelancersPreviewModel = new FreelancersPreviewModel(); $list = $freelancersPreviewModel->getListByUids($frl_ids, $categoty_id, $prof_id); $tmp_tu_uids = $tu_frl_ids; foreach ($list as $item) { //Если отключена вкладка ТУ то их исключаем if (!$item || $item->type == FreelancersPreviewModel::TYPE_TU && !in_array($item->user_id, $tmp_tu_uids)) { continue; } //Инициализируем данные юзера в работе/услуге пока только логин нужен $key = $frl_ids_map[$item->user_id]; $item->setUser(array('login' => $this->results[$key]['login'])); //Инитим виджет если его нет if (!isset($this->results[$key]['preview'])) { $this->results[$key]['preview'] = new FreelancersPreviewWidget(); } //Добавляем работу в виджет $this->results[$key]['preview']->addItem($item); //Исключаем из дальнейшей обработки unset($frl_ids[$key], $tu_frl_ids[$key]); } //------------------------------------------------------------------ $this->works = null; if ($frl_ids) { $this->works = $this->getUsersWorks($frl_ids, $uid); } //------------------------------------------------------------------ //Если у пользователя не отображатся портфолио //то можно показать 3 последнии ТУ $exist_uids = $this->works ? array_keys($this->works) : array(); $tu_uids = array_diff($frl_ids, $exist_uids); if ($tu_uids) { require_once ABS_PATH . '/tu/models/TServiceModel.php'; $tserviceModel = new TServiceModel(); if ($list = $tserviceModel->getListByUids($tu_uids, 3, freelancer::CATALOG_PORTFOLIO_MEM_LIFE)) { $current_user_tu_ids = array(); foreach ($list as $item) { $key = $frl_ids_map[$item['user_id']]; $item['login'] = $this->results[$key]['login']; $this->results[$key]['tservices'][] = $item; if ($item['user_id'] == $uid) { $current_user_tu_ids[] = $item['id']; } } if (!empty($current_user_tu_ids)) { FreelancersPreviewModel::setExistPreviewData(FreelancersPreviewModel::TYPE_TU, $current_user_tu_ids); } } } } }