206 $query = WorkgroupTable::query();
224 $query->where(
'VISIBLE',
$options[
'visible'] ?
'Y' :
'N');
229 $query->where(
'OPENED',
$options[
'open'] ?
'Y' :
'N');
234 $query->where(
'CLOSED',
$options[
'closed'] ?
'Y' :
'N');
239 $query->where(
'LANDING',
$options[
'landing'] ?
'Y' :
'N');
244 $query->where(
'ACTIVE',
$options[
'active'] ?
'Y' :
'N');
249 $query->where(
'PROJECT',
$options[
'project'] ?
'Y' :
'N');
256 Filter\Helper::matchAgainstWildcard(
257 Content::prepareStringToken(
$options[
'searchQuery']),
264 $currentUserId = (!empty(
$options[
'currentUserId']) && is_int(
$options[
'currentUserId'])
267 $query->registerRuntimeField(
270 WorkgroupSiteTable::class,
271 Join::on(
'this.ID',
'ref.GROUP_ID'),
272 [
'join_type' =>
'INNER']
277 $query->where(
'PROJECT_SITE.SITE_ID', $siteId);
282 ||
$options[
'myProjectsOnly'] ===
true
284 && !\CSocNetUser::isCurrentUserModuleAdmin()
287 $query->registerRuntimeField(
290 UserToGroupTable::class,
291 Join::on(
'this.ID',
'ref.GROUP_ID')
292 ->where(
'ref.USER_ID', $currentUserId)
298 [
'join_type' =>
'INNER']
305 $query->registerRuntimeField(
308 WorkgroupViewTable::class,
309 Join::on(
'this.ID',
'ref.GROUP_ID')->where(
'ref.USER_ID', $currentUserId),
310 [
'join_type' =>
'INNER']
315 $extranetSiteId = Option::get(
'extranet',
'extranet_site');
318 && ModuleManager::isModuleInstalled(
'extranet') ? $extranetSiteId : false
322 $query->registerRuntimeField(
325 WorkgroupSiteTable::class,
326 Join::on(
'this.ID',
'ref.GROUP_ID')->where(
'ref.SITE_ID', $extranetSiteId),
327 [
'join_type' =>
'LEFT']
331 $query->registerRuntimeField(
333 'IS_EXTRANET',
'CASE WHEN %s IS NOT NULL THEN \'Y\' ELSE \'N\' END', [
'EXTRANET_PROJECT.GROUP_ID']
337 $query->addSelect(
'IS_EXTRANET');
343 $query->whereNotNull(
'EXTRANET_PROJECT.GROUP_ID');
347 $query->whereNull(
'EXTRANET_PROJECT.GROUP_ID');
356 : (isset(
$options[
'!projectId']) ?
'!projectId' :
null)
359 if (isset(
$options[$projectFilter]))
363 foreach (
$options[$projectFilter] as $id)
365 $projectIds[] = (int)$id;
368 $projectIds = array_unique($projectIds);
370 if (!empty($projectIds))
372 if ($projectFilter ===
'projectId')
374 $query->whereIn(
'ID', $projectIds);
378 $query->whereNotIn(
'ID', $projectIds);
382 else if (!is_array(
$options[$projectFilter]) && (
int)
$options[$projectFilter] > 0)
384 if ($projectFilter ===
'projectId')
386 $query->where(
'ID', (
int)
$options[$projectFilter]);
390 $query->whereNot(
'ID', (
int)
$options[$projectFilter]);
396 $projectFilter ===
'projectId'
398 && count($projectIds) > 1
401 $query->registerRuntimeField(
403 'ID_SEQUENCE',
'FIELD(%s, ' . implode(
',', $projectIds) .
')',
'ID'
407 $query->setOrder(
'ID_SEQUENCE');
411 $query->setOrder(
$options[
'order']);
415 $query->setOrder([
'NAME' =>
'asc']);
418 $isUserModuleAdmin = \CSocNetUser::isUserModuleAdmin($currentUserId, $siteId);
426 foreach (array_keys(
$options[
'features']) as $feature)
428 if (!self::isAllowedFeatures($feature))
430 return new EO_Workgroup_Collection();
436 Join::on(
'this.ID',
'ref.ENTITY_ID')
438 ->where(
'ref.FEATURE', $feature)
439 ->where(
'ref.ACTIVE',
'N'),
440 [
'join_type' =>
'LEFT']
442 $query->registerRuntimeField($featureField);
444 $query->whereNull(
"BF_{$feature}.ENTITY_ID");
447 if (!$isUserModuleAdmin)
453 if ($featuresPermissionsQuery)
455 $query->whereIn(
'ID', $featuresPermissionsQuery);
462 $query->setLimit(
$options[
'limit']);
464 elseif ($projectFilter !==
'projectId' || empty($projectIds))
466 $query->setLimit(100);
469 return $query->exec()->fetchCollection();
523 $helper = \Bitrix\Main\Application::getConnection()->getSqlHelper();
524 $globalFeatures = \CSocNetAllowed::getAllowedFeatures();
526 $workWithClosedGroups = (Option::get(
'socialnetwork',
'work_with_closed_groups',
'N') ===
'Y');
528 $query = new \Bitrix\Main\Entity\Query(WorkgroupTable::getEntity());
529 $query->addSelect(
'ID');
531 if ($currentUserId > 0)
533 $query->registerRuntimeField(
new Reference(
535 UserToGroupTable::getEntity(),
536 Join::on(
'this.ID',
'ref.GROUP_ID')
537 ->where(
'ref.USER_ID', $currentUserId),
538 [
'join_type' =>
'INNER' ]
544 $featureEntity = clone FeatureTable::getEntity();
546 foreach ($featuresList as $feature => $operationsList)
548 if (empty($operationsList))
556 foreach ($globalFeatures[$feature][
'operations'] as $operation => $perms)
559 !in_array($operation, $operationsList,
true)
572 $query->registerRuntimeField(
new Reference(
575 Join::on(
'this.ID',
'ref.ENTITY_ID')
577 ->where(
'ref.FEATURE', $feature),
578 [
'join_type' =>
'LEFT' ]
583 FeaturePermTable::class,
584 Join::on(
'this.ID',
'ref.FEATURE_ID'),
585 [
'join_type' =>
'LEFT' ]
590 ->whereIn(
"F_{$feature}.FP_{$feature}.OPERATION_ID", $operationsList)
591 ->whereNull(
"F_{$feature}.FP_{$feature}.OPERATION_ID")
594 if ($currentUserId > 0)
596 $minOperationsList = ($globalFeatures[$feature][
'minoperation'] ?? []);
597 if (!is_array($minOperationsList))
599 $minOperationsList = [ $minOperationsList ];
602 $conditionsList = [];
605 if (!$workWithClosedGroups && !empty($minOperationsList))
607 $minOperations = implode(
', ', array_map(
static function($operation) use ($helper) {
return "'" . $helper->forSql($operation) .
"'"; }, $minOperationsList));
608 $conditionsList[] =
"WHEN %s = 'Y' AND %s NOT IN ({$minOperations}) THEN 'A'";
609 $substitutes[] =
'CLOSED';
610 $substitutes[] =
"F_{$feature}.FP_{$feature}.OPERATION_ID";
613 $conditionsList[] =
"WHEN %s = 'N' AND %s IN ('N', 'L') THEN 'K'";
614 $substitutes[] =
'VISIBLE';
615 $substitutes[] =
"F_{$feature}.FP_{$feature}.ROLE";
617 $conditionsList[] =
'WHEN %s IS NOT NULL THEN %s';
618 $substitutes[] =
"F_{$feature}.FP_{$feature}.ROLE";
619 $substitutes[] =
"F_{$feature}.FP_{$feature}.ROLE";
621 $conditions = implode(
' ', $conditionsList);
624 "MIN_PERMISSION_{$feature}",
625 "CASE {$conditions} ELSE '{$defaultPerm}' END",
629 $query->registerRuntimeField(
631 "HAS_ACCESS_{$feature}",
632 'CASE WHEN %s <= %s THEN 1 ELSE 0 END',
635 "MIN_PERMISSION_{$feature}",
639 $query->where(
"HAS_ACCESS_{$feature}", 1);
644 "MIN_PERMISSION_{$feature}",
645 "CASE WHEN %s IS NOT NULL THEN %s ELSE '{$defaultPerm}' END",
647 "F_{$feature}.FP_{$feature}.ROLE",
648 "F_{$feature}.FP_{$feature}.ROLE"
652 $query->where(
"MIN_PERMISSION_{$feature}",
'N');
656 return ($hasFilter ? $query :
false);
660 EO_Workgroup_Collection $projects, array $features,
int $userId,
string $siteId
663 if (empty($features))
668 $projectIds = $projects->getIdList();
669 foreach ($features as $feature => $operations)
671 $availableIds = \CSocNetFeatures::isActiveFeature(SONET_ENTITY_GROUP, $projectIds, $feature);
672 if (!is_array($availableIds))
674 return new EO_Workgroup_Collection();
677 $hasUnavailableId =
false;
678 foreach ($availableIds as $projectId => $isAvailable)
682 $hasUnavailableId =
true;
683 $projects->removeByPrimary($projectId);
687 if ($hasUnavailableId)
689 $projectIds = $projects->getIdList();
693 $isUserModuleAdmin = \CSocNetUser::isUserModuleAdmin($userId, $siteId);
694 $availableIdsByFeature = [];
697 foreach ($features as $feature => $operations)
699 if (!is_array($operations) || empty($operations))
701 $availableIdsByFeature[] = $projectIds;
705 $availableFeatureIds = [];
707 foreach ($operations as $operation)
714 $availableIds = \CSocNetFeaturesPerms::canPerformOperation(
723 if (!is_array($availableIds))
728 foreach ($availableIds as $projectId => $isAvailable)
732 $availableFeatureIds[] = $projectId;
736 $ids = array_diff($ids, $availableFeatureIds);
739 $availableIdsByFeature[] = $availableFeatureIds;
743 if (!empty($availableIdsByFeature))
746 count($availableIdsByFeature) > 1
747 ? call_user_func_array(
'array_intersect', $availableIdsByFeature)
748 : $availableIdsByFeature[0]
752 if (empty($availableIds))
754 return new EO_Workgroup_Collection();
757 $wrongIds = array_diff($projects->getIdList(), $availableIds);
758 foreach ($wrongIds as $wrongId)
760 $projects->removeByPrimary($wrongId);
785 $extranetSiteId = Option::get(
'extranet',
'extranet_site');
786 $extranetSiteId = ($extranetSiteId && ModuleManager::isModuleInstalled(
'extranet') ? $extranetSiteId :
false);
789 $extranetSiteId && $project->get(
'IS_EXTRANET') ===
'Y'
796 'id' => $project->getId(),
797 'entityId' =>
'project',
798 'entityType' => $entityType,
799 'title' => $project->getName(),
800 'avatar' => self::makeProjectAvatar($project),
802 'landing' => $project->getLanding(),
803 'active' => $project->getActive(),
804 'visible' => $project->getVisible(),
805 'closed' => $project->getClosed(),
806 'open' => $project->getOpened(),
807 'project' => $project->getProject(),
822 if (!empty($project->getImageId()))
824 $avatar = \CFile::resizeImageGet(
825 $project->getImageId(),
826 [
'width' => 100,
'height' => 100],
827 BX_RESIZE_IMAGE_EXACT,
831 return !empty($avatar[
'src']) ? $avatar[
'src'] :
null;
834 if (!empty($project->getAvatarType()))
836 $url = \Bitrix\Socialnetwork\Helper\Workgroup::getAvatarEntitySelectorUrl($project->getAvatarType());
837 return !empty($url) ? $url :
null;