function testGetGlobalTargetTypeForObject() { $this->assertEqual('global_plant', Role_Action_Target::getGlobalTargetTypeForObject(new Authoritative_Plant(['DB' => $this->DB]))); $this->assertEqual('global_plant', Role_Action_Target::getGlobalTargetTypeForObject(new Authoritative_Plant_Extra(['DB' => $this->DB]))); $this->assertEqual('global_metadata', Role_Action_Target::getGlobalTargetTypeForObject(new Metadata_Structure(['DB' => $this->DB]))); $this->assertEqual('global_metadata', Role_Action_Target::getGlobalTargetTypeForObject(new Metadata_Term_Set(['DB' => $this->DB]))); $this->assertEqual('global_metadata', Role_Action_Target::getGlobalTargetTypeForObject(new Metadata_Term_Value(['DB' => $this->DB]))); $this->assertEqual('global_metadata', Role_Action_Target::getGlobalTargetTypeForObject(new Metadata_Reference(['DB' => $this->DB]))); $this->assertEqual('global_notebook', Role_Action_Target::getGlobalTargetTypeForObject(new Notebook(['DB' => $this->DB]))); $this->assertEqual('global_notebook', Role_Action_Target::getGlobalTargetTypeForObject(new Notebook_Page(['DB' => $this->DB]))); $this->assertEqual('global_notebook', Role_Action_Target::getGlobalTargetTypeForObject(new Notebook_Page_Field(['DB' => $this->DB]))); $this->assertEqual('global_specimen', Role_Action_Target::getGlobalTargetTypeForObject(new Specimen(['DB' => $this->DB]))); $this->assertEqual('global_specimen', Role_Action_Target::getGlobalTargetTypeForObject(new Specimen_Image(['DB' => $this->DB]))); $this->assertEqual(false, Role_Action_Target::getGlobalTargetTypeForObject(new Action(['DB' => $this->DB]))); }
public function canActOnTarget($action, $target) { // system admin -> always yes // owner of target -> always yes, except for verification // all other situatons -> check role action targets // - matching globals -> yes // - specifics // + gets messy // - otherwise -> no if (is_string($action)) { global $ACTIONS; $action = $ACTIONS[$action]; } // system admin -> always yes if ($this->flag_is_system_admin) { return true; } // util_prePrintR($action); // util_prePrintR($target); // owner of target -> always yes, except for verification if ($target->user_id == $this->user_id) { if ($action->name != 'verify') { return true; } } // view & list is controlled by flags on the object rather than explicit permissions / access records if ($action->name == 'view' || $action->name == 'list') { if (array_key_exists('flag_active', $target->fieldValues)) { if ($target->flag_active) { return true; } } elseif (array_key_exists('flag_workflow_published', $target->fieldValues)) { if ($target->flag_workflow_published && $target->flag_workflow_validated) { return true; } } } // all other situatons -> check role action targets $this->cacheRoleActionTargets(); // - matching globals -> yes $target_global_type = Role_Action_Target::getGlobalTargetTypeForObject($target); if (in_array($target_global_type, array_keys($this->cached_role_action_targets_hash_by_target_type_by_id))) { foreach ($this->cached_role_action_targets_hash_by_target_type_by_id[$target_global_type] as $glob_rat) { if ($glob_rat->action_id == $action->action_id) { return true; } } } // util_prePrintR($this->cached_role_action_targets_hash_by_target_type_by_id); // - specifics // + gets messy // if the allowed target types do not contain the specific type of the target in question, then no need to go further // get a list of all the specific ids to check. This gets a bit messy as we have to climb or include a hierarchy depending on what exactly the target is // util_prePrintR($target); $ids_to_check = array(); $target_class = get_class($target); switch ($target_class) { case 'Authoritative_Plant': $ids_to_check = array($target->authoritative_plant_id); break; case 'Authoritative_Plant_Extra': // can act on this if can act on the plant return $this->canActOnTarget($action, $target->getAuthoritativePlant()); break; case 'Metadata_Structure': // can edit this if can edit itself or any parent $ids_to_check = Db_Linked::arrayOfAttrValues($target->getLineage(), 'metadata_structure_id'); break; case 'Metadata_Term_Set': // can edit if can edit any structure that uses this term set $structures = Metadata_Structure::getAllFromDb(['metadata_term_set_id' => $target->metadata_term_set_id], $this->dbConnection); $ids_to_check = array(); foreach ($structures as $s) { $ids_to_check = array_merge($ids_to_check, Db_Linked::arrayOfAttrValues($s->getLineage(), 'metadata_structure_id')); } break; case 'Metadata_Term_Value': // can edit if can edit any structure that uses the term set for which this is a value return $this->canActOnTarget($action, Metadata_Term_Set::getOneFromDb(['metadata_term_set_id' => $target->metadata_term_set_id], $this->dbConnection)); break; case 'Metadata_Reference': // can edit if can edit anything to which this refers return $this->canActOnTarget($action, $target->getReferrent()); break; case 'Notebook': $ids_to_check = array($target->notebook_id); break; case 'Notebook_Page': // can act on if can act on the notebook that contains this page return $this->canActOnTarget($action, $target->getNotebook()); break; case 'Notebook_Page_Field': // can act on if can act on the notebook that contains the notebook page that this page field return $this->canActOnTarget($action, $target->getNotebookPage()->getNotebook()); break; case 'Specimen': $ids_to_check = array($target->specimen_id); break; case 'Specimen_Image': // can act on if can act on the specimen return $this->canActOnTarget($action, $target->getSpecimen()); break; default: break; } // util_prePrintR($ids_to_check); // util_prePrintR($this->cached_role_action_targets_hash_by_target_type_by_id); $target_specific_type = Role_Action_Target::getSpecificTargetTypeForObject($target); if (!in_array($target_specific_type, array_keys($this->cached_role_action_targets_hash_by_target_type_by_id))) { return false; } foreach ($this->cached_role_action_targets_hash_by_target_type_by_id[$target_specific_type] as $spec_rat) { if ($spec_rat->action_id == $action->action_id && in_array($spec_rat->target_id, $ids_to_check)) { if ($action->name == 'view') { $actual_target = $spec_rat->getTargets()[0]; if (array_key_exists('flag_workflow_published', $actual_target->fieldValues)) { return $actual_target->flag_workflow_published && $actual_target->flag_workflow_validated; } } return true; } } return false; }