/**
  *	...
  */
 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");
         }
     }
 }