/** * ... */ public function MakeSelectFilter($sClass, $aAllowedOrgs, $aSettings = array(), $sAttCode = null) { if ($sAttCode == null) { $sAttCode = $this->GetOwnerOrganizationAttCode($sClass); } if (empty($sAttCode)) { return $oFilter = new DBObjectSearch($sClass); } $oExpression = new FieldExpression($sAttCode, $sClass); $oFilter = new DBObjectSearch($sClass); $oListExpr = ListExpression::FromScalars($aAllowedOrgs); $oCondition = new BinaryExpression($oExpression, 'IN', $oListExpr); $oFilter->AddConditionExpression($oCondition); if ($this->HasSharing()) { if ($sAttCode == 'id' && isset($aSettings['bSearchMode']) && $aSettings['bSearchMode']) { // Querying organizations (or derived) // and the expected list of organizations will be used as a search criteria // Therefore the query can also return organization having objects shared with the allowed organizations // // 1) build the list of organizations sharing something with the allowed organizations // Organization <== sharing_org_id == SharedObject having org_id IN {user orgs} $oShareSearch = new DBObjectSearch('SharedObject'); $oOrgField = new FieldExpression('org_id', 'SharedObject'); $oShareSearch->AddConditionExpression(new BinaryExpression($oOrgField, 'IN', $oListExpr)); $oSearchSharers = new DBObjectSearch('Organization'); $oSearchSharers->AllowAllData(); $oSearchSharers->AddCondition_ReferencedBy($oShareSearch, 'sharing_org_id'); $aSharers = array(); foreach ($oSearchSharers->ToDataArray(array('id')) as $aRow) { $aSharers[] = $aRow['id']; } // 2) Enlarge the overall results: ... OR id IN(id1, id2, id3) if (count($aSharers) > 0) { $oSharersList = ListExpression::FromScalars($aSharers); $oFilter->MergeConditionExpression(new BinaryExpression($oExpression, 'IN', $oSharersList)); } } $aShareProperties = SharedObject::GetSharedClassProperties($sClass); if ($aShareProperties) { $sShareClass = $aShareProperties['share_class']; $sShareAttCode = $aShareProperties['attcode']; $oSearchShares = new DBObjectSearch($sShareClass); $oSearchShares->AllowAllData(); $sHierarchicalKeyCode = MetaModel::IsHierarchicalClass('Organization'); $oOrgField = new FieldExpression('org_id', $sShareClass); $oSearchShares->AddConditionExpression(new BinaryExpression($oOrgField, 'IN', $oListExpr)); $aShared = array(); foreach ($oSearchShares->ToDataArray(array($sShareAttCode)) as $aRow) { $aShared[] = $aRow[$sShareAttCode]; } if (count($aShared) > 0) { $oObjId = new FieldExpression('id', $sClass); $oSharedIdList = ListExpression::FromScalars($aShared); $oFilter->MergeConditionExpression(new BinaryExpression($oObjId, 'IN', $oSharedIdList)); } } } // if HasSharing return $oFilter; }
public function IsActionAllowed($oUser, $sClass, $iActionCode, $oInstanceSet = null) { $this->LoadCache(); $aObjectPermissions = $this->GetUserActionGrant($oUser, $sClass, $iActionCode); $iPermission = $aObjectPermissions['permission']; // Note: In most cases the object set is ignored because it was interesting to optimize for huge data sets // and acceptable to consider only the root class of the object set if ($iPermission != UR_ALLOWED_YES) { // It is already NO for everyone... that's the final word! } elseif ($iActionCode == UR_ACTION_READ) { // We are protected by GetSelectFilter: the object set contains objects allowed or shared for reading } elseif ($iActionCode == UR_ACTION_BULK_READ) { // We are protected by GetSelectFilter: the object set contains objects allowed or shared for reading } elseif ($oInstanceSet) { // We are protected by GetSelectFilter: the object set contains objects allowed or shared for reading // We have to answer NO for objects shared for reading purposes if (self::HasSharing()) { $aClassProps = SharedObject::GetSharedClassProperties($sClass); if ($aClassProps) { // This class is shared, GetSelectFilter may allow some objects for read only // But currently we are checking wether the objects might be written... // Let's exclude the objects based on the relevant criteria $sOrgAttCode = self::GetOwnerOrganizationAttCode($sClass); if (!is_null($sOrgAttCode)) { $aUserOrgs = $this->GetUserOrgs($oUser, $sClass); if (!is_null($aUserOrgs) && count($aUserOrgs) > 0) { $iCountNO = 0; $iCountYES = 0; $oInstanceSet->Rewind(); while ($oObject = $oInstanceSet->Fetch()) { $iOrg = $oObject->Get($sOrgAttCode); if (in_array($iOrg, $aUserOrgs)) { $iCountYES++; } else { $iCountNO++; } } if ($iCountNO == 0) { $iPermission = UR_ALLOWED_YES; } elseif ($iCountYES == 0) { $iPermission = UR_ALLOWED_NO; } else { $iPermission = UR_ALLOWED_DEPENDS; } } } } } } return $iPermission; }
function saveSharedObject($object, $user) { $ou = SharedObjects::findOne(array('conditions' => "object_id = " . $object->getId() . " AND object_manager = '" . $object->getObjectManagerName() . "' AND user_id = " . $user->getId())); if (!$ou) { try { DB::beginWork(); $ou = new SharedObject(); $ou->setObjectId($object->getId()); $ou->setObjectManager($object->getObjectManagerName()); $ou->setUserId($user->getId()); $ou->setCreatedOn(DateTimeValueLib::now()); $ou->setCreatedById(logged_user()->getId()); $ou->save(); DB::commit(); } catch (Exception $e) { DB::rollback(); flash_error($e->getMessage()); ajx_current("empty"); } } }