function apply_association_filters($dimension, $dimension_members, $selected_members)
 {
     $members_to_retrieve = array();
     $all_associated_members_ids = array();
     foreach ($selected_members as $member) {
         // ignore selected members that are from the same dimension that is going to be filtered
         if (!$member instanceof Member || $member->getDimensionId() == $dimension->getId()) {
             continue;
         }
         // get dimension associations for selected member object type and the dimension to be filtered
         $association_ids = DimensionMemberAssociations::getAllAssociationIds($member->getDimensionId(), $dimension->getId(), $member->getObjectTypeId());
         if (count($association_ids) > 0) {
             $associated_members_ids = array();
             foreach ($association_ids as $id) {
                 $property_members_members = null;
                 $property_members_props = null;
                 $association = DimensionMemberAssociations::findById($id);
                 //	$children = $member->getAllChildrenInHierarchy();
                 if ($association->getDimensionId() == $dimension->getId()) {
                     if (is_null($property_members_members)) {
                         $property_members_members = MemberPropertyMembers::getAllPropertyMembers($id);
                     }
                     $tmp_assoc_member_ids = array_var($property_members_members, $member->getId(), array());
                     /*		foreach ($children as $child){
                     							$tmp_assoc_member_ids = array_merge($tmp_assoc_member_ids, array_var($property_members_members, $child->getId(), array()));
                     						}
                     				*/
                     $associated_members_ids = array_unique(array_merge($associated_members_ids, $tmp_assoc_member_ids));
                 } else {
                     if (is_null($property_members_props)) {
                         $property_members_props = MemberPropertyMembers::getAllPropertyMembers($id, true);
                     }
                     $tmp_assoc_member_ids = array_var($property_members_props, $member->getId(), array());
                     /*		foreach ($children as $child){
                     							$tmp_assoc_member_ids = array_merge($tmp_assoc_member_ids, array_var($property_members_props, $child->getId(), array()));
                     						}
                     				*/
                     $associated_members_ids = array_unique(array_merge($associated_members_ids, $tmp_assoc_member_ids));
                 }
             }
             $all_associated_members_ids[] = array_unique($associated_members_ids);
         }
     }
     if (isset($association_ids) && count($association_ids) > 0 && count($all_associated_members_ids) > 0) {
         $intersection = array_var($all_associated_members_ids, 0);
         if (count($all_associated_members_ids) > 1) {
             $k = 1;
             while ($k < count($all_associated_members_ids)) {
                 $intersection = array_intersect($intersection, $all_associated_members_ids[$k++]);
             }
         }
         $all_associated_members_ids = $intersection;
         if (count($all_associated_members_ids) > 0) {
             $dimension_member_ids = array();
             foreach ($dimension_members as $dm) {
                 $dimension_member_ids[] = $dm->getId();
             }
             $members_to_retrieve_ids = array();
             $associated_members = Members::findAll(array('conditions' => 'id IN (' . implode(',', $all_associated_members_ids) . ')'));
             foreach ($associated_members as $associated_member) {
                 $context_hierarchy_members = $associated_member->getAllParentMembersInHierarchy(true);
                 foreach ($context_hierarchy_members as $context_member) {
                     if (!in_array($context_member->getId(), $members_to_retrieve_ids) && in_array($context_member->getId(), $dimension_member_ids)) {
                         $members_to_retrieve[$context_member->getName() . "_" . $context_member->getId()] = $context_member;
                         $members_to_retrieve_ids[] = $context_member->getId();
                     }
                 }
             }
             // alphabetical order
             $members_to_retrieve = array_ksort($members_to_retrieve);
         }
     } else {
         $members_to_retrieve = $dimension_members;
     }
     return $members_to_retrieve;
 }
 function saveMember($member_data, Member $member, $is_new = true)
 {
     try {
         DB::beginWork();
         if (!$is_new) {
             $old_parent = $member->getParentMemberId();
         }
         $member->setFromAttributes($member_data);
         /* @var $member Member */
         $object_type = ObjectTypes::findById($member->getObjectTypeId());
         if (!$object_type instanceof ObjectType) {
             throw new Exception(lang("you must select a valid object type"));
         }
         if ($member->getParentMemberId() == 0) {
             $dot = DimensionObjectTypes::findById(array('dimension_id' => $member->getDimensionId(), 'object_type_id' => $member->getObjectTypeId()));
             if (!$dot->getIsRoot()) {
                 throw new Exception(lang("member cannot be root", lang($object_type->getName())));
             }
             $member->setDepth(1);
         } else {
             $allowedParents = $this->getAssignableParents($member->getDimensionId(), $member->getObjectTypeId());
             if (!$is_new) {
                 $childrenIds = $member->getAllChildrenIds(true);
             }
             $hasValidParent = false;
             if ($member->getId() == $member->getParentMemberId() || !$is_new && in_array($member->getParentMemberId(), $childrenIds)) {
                 throw new Exception(lang("invalid parent member"));
             }
             foreach ($allowedParents as $parent) {
                 if ($parent['id'] == $member->getParentMemberId()) {
                     $hasValidParent = true;
                     break;
                 }
             }
             if (!$hasValidParent) {
                 throw new Exception(lang("invalid parent member"));
             }
             $parent = Members::findById($member->getParentMemberId());
             if ($parent instanceof Member) {
                 $member->setDepth($parent->getDepth() + 1);
             } else {
                 $member->setDepth(1);
             }
         }
         if ($object_type->getType() == 'dimension_object') {
             $handler_class = $object_type->getHandlerClass();
             if ($is_new || $member->getObjectId() == 0) {
                 eval('$dimension_object = ' . $handler_class . '::instance()->newDimensionObject();');
             } else {
                 $dimension_object = Objects::findObject($member->getObjectId());
             }
             if ($dimension_object) {
                 $dimension_object->modifyMemberValidations($member);
                 $dimension_obj_data = array_var($_POST, 'dim_obj');
                 if (!array_var($dimension_obj_data, 'name')) {
                     $dimension_obj_data['name'] = $member->getName();
                 }
                 eval('$fields = ' . $handler_class . '::getPublicColumns();');
                 foreach ($fields as $field) {
                     if (array_var($field, 'type') == DATA_TYPE_DATETIME) {
                         $dimension_obj_data[$field['col']] = getDateValue($dimension_obj_data[$field['col']]);
                     }
                 }
                 $member->save();
                 $dimension_object->setFromAttributes($dimension_obj_data, $member);
                 $dimension_object->save();
                 $member->setObjectId($dimension_object->getId());
                 $member->save();
                 Hook::fire("after_add_dimension_object_member", $member, $null);
             }
         } else {
             $member->save();
         }
         // Other dimensions member restrictions
         $restricted_members = array_var($_POST, 'restricted_members');
         if (is_array($restricted_members)) {
             MemberRestrictions::clearRestrictions($member->getId());
             foreach ($restricted_members as $dim_id => $dim_members) {
                 foreach ($dim_members as $mem_id => $member_restrictions) {
                     $restricted = isset($member_restrictions['restricted']);
                     if ($restricted) {
                         $order_num = array_var($member_restrictions, 'order_num', 0);
                         $member_restriction = new MemberRestriction();
                         $member_restriction->setMemberId($member->getId());
                         $member_restriction->setRestrictedMemberId($mem_id);
                         $member_restriction->setOrder($order_num);
                         $member_restriction->save();
                     }
                 }
             }
         }
         // Save member property members (also check for required associations)
         if (array_var($_POST, 'save_properties')) {
             $required_association_ids = DimensionMemberAssociations::getRequiredAssociatations($member->getDimensionId(), $member->getObjectTypeId(), true);
             $missing_req_association_ids = array_fill_keys($required_association_ids, true);
             // if keeps record change is_active, if not delete record
             $old_properties = MemberPropertyMembers::getAssociatedPropertiesForMember($member->getId());
             foreach ($old_properties as $property) {
                 $association = DimensionMemberAssociations::findById($property->getAssociationId());
                 if (!$association->getKeepsRecord()) {
                     $property->delete();
                 }
             }
             $new_properties = array();
             $associated_members = array_var($_POST, 'associated_members', array());
             foreach ($associated_members as $prop_member_id => $assoc_id) {
                 $active_association = null;
                 if (isset($missing_req_association_ids[$assoc_id])) {
                     $missing_req_association_ids[$assoc_id] = false;
                 }
                 $conditions = "`association_id` = {$assoc_id} AND `member_id` = " . $member->getId() . " AND `is_active` = 1";
                 $active_associations = MemberPropertyMembers::find(array('conditions' => $conditions));
                 if (count($active_associations) > 0) {
                     $active_association = $active_associations[0];
                 }
                 $association = DimensionMemberAssociations::findById($assoc_id);
                 if ($active_association instanceof MemberPropertyMember) {
                     if ($active_association->getPropertyMemberId() != $prop_member_id) {
                         if ($association->getKeepsRecord()) {
                             $active_association->setIsActive(false);
                             $active_association->save();
                         }
                         // save current association
                         $mpm = new MemberPropertyMember();
                         $mpm->setAssociationId($assoc_id);
                         $mpm->setMemberId($member->getId());
                         $mpm->setPropertyMemberId($prop_member_id);
                         $mpm->setIsActive(true);
                         $mpm->save();
                         $new_properties[] = $mpm;
                     }
                 } else {
                     // save current association
                     $mpm = new MemberPropertyMember();
                     $mpm->setAssociationId($assoc_id);
                     $mpm->setMemberId($member->getId());
                     $mpm->setPropertyMemberId($prop_member_id);
                     $mpm->setIsActive(true);
                     $mpm->save();
                     $new_properties[] = $mpm;
                 }
             }
             $missing_names = array();
             $missing_count = 0;
             foreach ($missing_req_association_ids as $assoc => $missing) {
                 $assoc_instance = DimensionMemberAssociations::findById($assoc);
                 if ($assoc_instance instanceof DimensionMemberAssociation) {
                     $assoc_dim = Dimensions::getDimensionById($assoc_instance->getAssociatedDimensionMemberAssociationId());
                     if ($assoc_dim instanceof Dimension) {
                         if (!in_array($assoc_dim->getName(), $missing_names)) {
                             $missing_names[] = $assoc_dim->getName();
                         }
                     }
                 }
                 if ($missing) {
                     $missing_count++;
                 }
             }
             if ($missing_count > 0) {
                 throw new Exception(lang("missing required associations", implode(", ", $missing_names)));
             }
             $args = array($member, $old_properties, $new_properties);
             Hook::fire('edit_member_properties', $args, $ret);
         }
         if ($is_new) {
             // set all permissions for the creator
             $dimension = $member->getDimension();
             $allowed_object_types = array();
             $dim_obj_types = $dimension->getAllowedObjectTypeContents();
             foreach ($dim_obj_types as $dim_obj_type) {
                 // To draw a row for each object type of the dimension
                 if (!in_array($dim_obj_type->getContentObjectTypeId(), $allowed_object_types) && $dim_obj_type->getDimensionObjectTypeId() == $member->getObjectTypeId()) {
                     $allowed_object_types[] = $dim_obj_type->getContentObjectTypeId();
                 }
             }
             $allowed_object_types[] = $object_type->getId();
             foreach ($allowed_object_types as $ot) {
                 $cmp = ContactMemberPermissions::findOne(array('conditions' => 'permission_group_id = ' . logged_user()->getPermissionGroupId() . ' AND member_id = ' . $member->getId() . ' AND object_type_id = ' . $ot));
                 if (!$cmp instanceof ContactMemberPermission) {
                     $cmp = new ContactMemberPermission();
                     $cmp->setPermissionGroupId(logged_user()->getPermissionGroupId());
                     $cmp->setMemberId($member->getId());
                     $cmp->setObjectTypeId($ot);
                 }
                 $cmp->setCanWrite(1);
                 $cmp->setCanDelete(1);
                 $cmp->save();
             }
             // set all permissions for permission groups that has allow all in the dimension
             $permission_groups = ContactDimensionPermissions::findAll(array("conditions" => array("`dimension_id` = ? AND `permission_type` = 'allow all'", $dimension->getId())));
             if (is_array($permission_groups)) {
                 foreach ($permission_groups as $pg) {
                     foreach ($allowed_object_types as $ot) {
                         $cmp = ContactMemberPermissions::findById(array('permission_group_id' => $pg->getPermissionGroupId(), 'member_id' => $member->getId(), 'object_type_id' => $ot));
                         if (!$cmp instanceof ContactMemberPermission) {
                             $cmp = new ContactMemberPermission();
                             $cmp->setPermissionGroupId($pg->getPermissionGroupId());
                             $cmp->setMemberId($member->getId());
                             $cmp->setObjectTypeId($ot);
                         }
                         $cmp->setCanWrite(1);
                         $cmp->setCanDelete(1);
                         $cmp->save();
                     }
                 }
             }
             // Inherit permissions from parent node, if they are not already set
             if ($member->getDepth() && $member->getParentMember()) {
                 $parentNodeId = $member->getParentMember()->getId();
                 $condition = "member_id = {$parentNodeId}";
                 foreach (ContactMemberPermissions::instance()->findAll(array("conditions" => $condition)) as $parentPermission) {
                     /* @var $parentPermission ContactMemberPermission */
                     $g = $parentPermission->getPermissionGroupId();
                     $t = $parentPermission->getObjectTypeId();
                     $w = $parentPermission->getCanWrite();
                     $d = $parentPermission->getCanDelete();
                     $existsCondition = "member_id = " . $member->getId() . " AND permission_group_id= {$g} AND object_type_id = {$t}";
                     if (!ContactMemberPermissions::instance()->count(array("conditions" => $existsCondition))) {
                         $newPermission = new ContactMemberPermission();
                         $newPermission->setPermissionGroupId($g);
                         $newPermission->setObjectTypeId($t);
                         $newPermission->setCanWrite($w);
                         $newPermission->setCanDelete($d);
                         $newPermission->setMemberId($member->getId());
                         $newPermission->save();
                     }
                 }
             }
             // Fill sharing table if is a dimension object (after permission creation);
             if (isset($dimension_object) && $dimension_object instanceof ContentDataObject) {
                 $dimension_object->addToSharingTable();
             }
         } else {
             // if parent changed rebuild object_members for every object in this member
             if ($old_parent != $member->getParentMemberId()) {
                 $sql = "SELECT om.object_id FROM " . TABLE_PREFIX . "object_members om WHERE om.member_id=" . $member->getId();
                 $object_ids = DB::executeAll($sql);
                 if (!is_array($object_ids)) {
                     $object_ids = array();
                 }
                 foreach ($object_ids as $row) {
                     $content_object = Objects::findObject($row['object_id']);
                     if (!$content_object instanceof ContentDataObject) {
                         continue;
                     }
                     $parent_ids = array();
                     if ($old_parent > 0) {
                         $all_parents = Members::findById($old_parent)->getAllParentMembersInHierarchy(true);
                         foreach ($all_parents as $p) {
                             $parent_ids[] = $p->getId();
                         }
                         if (count($parent_ids) > 0) {
                             DB::execute("DELETE FROM " . TABLE_PREFIX . "object_members WHERE object_id=" . $content_object->getId() . " AND member_id IN (" . implode(",", $parent_ids) . ")");
                         }
                     }
                     $content_object->addToMembers(array($member));
                     $content_object->addToSharingTable();
                 }
             }
         }
         DB::commit();
         flash_success(lang('success save member', lang(ObjectTypes::findById($member->getObjectTypeId())->getName()), $member->getName()));
         ajx_current("back");
         // Add od to array on new members
         if ($is_new) {
             $member_data['member_id'] = $member->getId();
         }
         evt_add("after member save", $member_data);
         return $member;
     } catch (Exception $e) {
         DB::rollback();
         flash_error($e->getMessage());
         ajx_current("empty");
     }
 }
 /**
  * 
  * 
  */
 function list_dimension_members($member_id, $context_dimension_id, $object_type_id, $allowed_member_type_ids)
 {
     if ($member_id != 0) {
         $contact_pg_ids = ContactPermissionGroups::getPermissionGroupIdsByContactCSV(logged_user()->getId(), false);
         $member = members::findById($member_id);
         $dimension = Dimensions::getDimensionById($context_dimension_id);
         if ($object_type_id != null) {
             $dimension_object_type_contents = $dimension->getObjectTypeContent($object_type_id);
             foreach ($dimension_object_type_contents as $dotc) {
                 $dot_id = $dotc->getDimensionObjectTypeId();
                 if (is_null($allowed_member_type_ids) || in_array($dot_id, $allowed_member_type_ids)) {
                     $allowed_object_type_ids[] = $dot_id;
                 }
             }
         }
         if ($dimension instanceof Dimension && $member instanceof Member) {
             if (!$dimension->getDefinesPermissions() || $dimension->hasAllowAllForContact($contact_pg_ids)) {
                 $dimension_members = $dimension->getAllMembers(false, "parent_member_id, name", true);
             } else {
                 if ($dimension->hasCheckForContact($contact_pg_ids)) {
                     $member_list = $dimension->getAllMembers(false, "parent_member_id, name", true);
                     $allowed_members = array();
                     foreach ($member_list as $dim_member) {
                         if (ContactMemberPermissions::instance()->contactCanReadMemberAll($contact_pg_ids, $dim_member->getId(), logged_user())) {
                             $allowed_members[] = $dim_member;
                         }
                     }
                     $dimension_members = $allowed_members;
                 }
             }
             $members_to_retrieve = array();
             $association_ids = DimensionMemberAssociations::getAllAssociationIds($member->getDimensionId(), $context_dimension_id);
             if (count($association_ids) > 0) {
                 $associated_members_ids_csv = '';
                 foreach ($association_ids as $id) {
                     $association = DimensionMemberAssociations::findById($id);
                     $children = $member->getAllChildrenInHierarchy();
                     if ($association->getDimensionId() == $context_dimension_id) {
                         $new_csv = MemberPropertyMembers::getAllMemberIds($id, $member_id);
                         $associated_members_ids_csv .= $new_csv != '' ? $new_csv . "," : '';
                         foreach ($children as $child) {
                             $new_csv = MemberPropertyMembers::getAllMemberIds($id, $child->getId());
                             $associated_members_ids_csv .= $new_csv != '' ? $new_csv . "," : '';
                         }
                     } else {
                         $new_csv = MemberPropertyMembers::getAllPropertyMemberIds($id, $member_id) . ",";
                         $associated_members_ids_csv .= $new_csv != '' ? $new_csv . "," : '';
                         foreach ($children as $child) {
                             $new_csv = MemberPropertyMembers::getAllPropertyMemberIds($id, $child->getId());
                             $associated_members_ids_csv .= $new_csv != '' ? $new_csv . "," : '';
                         }
                     }
                 }
                 $associated_members_ids = explode(',', $associated_members_ids_csv);
                 $associated_members_ids = array_unique($associated_members_ids);
             }
             if (isset($associated_members_ids) && count($associated_members_ids) > 0) {
                 foreach ($associated_members_ids as $id) {
                     $associated_member = Members::findById($id);
                     if (in_array($associated_member, $dimension_members)) {
                         $context_hierarchy_members = $associated_member->getAllParentMembersInHierarchy(true);
                         foreach ($context_hierarchy_members as $context_member) {
                             if (!in_array($context_member, $members_to_retrieve) && in_array($context_member, $dimension_members)) {
                                 $members_to_retrieve[$context_member->getName()] = $context_member;
                             }
                         }
                     }
                 }
                 // alphabetical order
                 $members_to_retrieve = array_ksort($members_to_retrieve);
             } else {
                 $members_to_retrieve[] = $dimension_members;
             }
             $membersset = array();
             foreach ($members_to_retrieve as $m) {
                 $membersset[$m->getId()] = true;
             }
             $members = array();
             // Todo adapt this code to call "buildMemberList" - (performance and code improvement)
             foreach ($members_to_retrieve as $m) {
                 if ($m->getArchivedById() > 0) {
                     continue;
                 }
                 if ($object_type_id != null) {
                     $selectable = in_array($m->getObjectTypeId(), $allowed_object_type_ids) ? true : false;
                 }
                 $tempParent = $m->getParentMemberId();
                 $x = $m;
                 while ($x instanceof Member && !isset($membersset[$tempParent])) {
                     $tempParent = $x->getParentMemberId();
                     $x = $x->getParentMember();
                 }
                 if (!$x instanceof Member) {
                     $tempParent = 0;
                 }
                 if ($dot = DimensionObjectTypes::instance()->findOne(array("conditions" => "\n\t\t\t\t\t\tdimension_id = " . $dimension->getId() . " AND\n\t\t\t\t\t\tobject_type_id = " . $m->getObjectTypeId()))) {
                     $memberOptions = $dot->getOptions(true);
                 } else {
                     $memberOptions = '';
                 }
                 /* @var $m Member */
                 $member = array("id" => $m->getId(), "name" => clean($m->getName()), "parent" => $tempParent, "realParent" => $m->getParentMemberId(), "object_id" => $m->getObjectId(), "options" => $memberOptions, "depth" => $m->getDepth(), "iconCls" => $m->getIconClass(), "selectable" => isset($selectable) ? $selectable : false, "dimension_id" => $m->getDimensionId(), "object_type_id" => $m->getObjectTypeId(), "allow_childs" => $m->allowChilds());
                 if ($oid = $m->getObjectId()) {
                     if ($obj = Objects::instance()->findObject($m->getObjectId())) {
                         $editUrl = $obj->getEditUrl();
                     }
                 }
                 // Member Actions
                 if (can_manage_dimension_members(logged_user())) {
                     if ($oid = $m->getObjectId()) {
                         if ($obj = Objects::instance()->findObject($m->getObjectId())) {
                             $editUrl = $obj->getEditUrl();
                         }
                     } else {
                         $editUrl = get_url('member', 'edit', array('id' => $m->getId()));
                     }
                     $member['actions'] = array(array('url' => $editUrl, 'text' => '', 'iconCls' => 'ico-edit'));
                 }
                 $members[] = $member;
             }
             return $members;
         }
         return null;
     } else {
         $members = $this->initial_list_dimension_members($context_dimension_id, $object_type_id, $allowed_member_type_ids);
         return $members;
     }
 }