function testRenderAsEdit()
 {
     $mds = Metadata_Structure::getOneFromDb(['metadata_structure_id' => 6001], $this->DB);
     $mds->loadTermSetAndValues();
     $mds->loadReferences();
     // name, description, details, term set ('none' is OK) - fields present
     // add/remove child structures - add button present, remove buttons present
     // re-order child structures - ordering handles and data fields present
     // ??? references ?
     $canonical = '';
     $canonical .= '<form id="form-edit-metadata-structure-base-data" action="/digitalfieldnotebooks/app_code/metadata_structure.php">' . "\n";
     $canonical .= '  <input type="hidden" name="action" value="update"/>' . "\n";
     $canonical .= '  <input type="hidden" id="metadata_structure_id" name="metadata_structure_id" value="' . $mds->metadata_structure_id . '"/>' . "\n";
     $canonical .= '  <div id="actions"><button id="edit-submit-control" class="btn btn-success" type="submit" name="edit-submit-control" value="update"><i class="icon-ok-sign icon-white"></i> Update</button>' . "\n";
     $canonical .= '  <a id="edit-cancel-control" class="btn" href="/digitalfieldnotebooks/app_code/metadata_structure.php?action=view&metadata_structure_id=6001"><i class="icon-remove"></i> Cancel</a>  <a id="edit-delete-metadata-structure-control" class="btn btn-danger" href="/digitalfieldnotebooks/app_code/metadata_structure.php?action=delete&metadata_structure_id=6001"><i class="icon-trash icon-white"></i> Delete</a>  </div>' . "\n";
     $canonical .= '<div id="edit-rendered_metadata_structure_6001" class="edit-rendered_metadata_structure" ' . $mds->fieldsAsDataAttribs() . '>' . "\n";
     $canonical .= '  <div class="metadata_lineage"><a href="' . APP_ROOT_PATH . '/app_code/metadata_structure.php?action=list">metadata</a> &gt;</div>' . "\n";
     $canonical .= '  <div class="metadata-parent-controls">' . util_lang('label_metadata_structure_change_parent') . ': ' . Metadata_Structure::renderControlSelectAllMetadataStructures('parent_metadata_structure_id', $mds->parent_metadata_structure_id, util_lang('metadata_root_level')) . '</div>' . "\n";
     $canonical .= '  <div class="metadata-structure-header">' . "\n";
     $canonical .= '    <h3><input id="" class="object-name-control" type="text" name="name" value="flower"/></h3>' . "\n";
     $canonical .= '    <div class="active-state-controls"><input type="checkbox" name="flag_active" value="1" checked="checked"/> ' . util_lang('active') . '</div>' . "\n";
     $canonical .= '    <div class="description-controls"><input title="brief description/summary" class="description-control" type="text" name="description" value="info about the flower"/></div>' . "\n";
     $canonical .= '    <div class="details-controls"><textarea title="additional information/details - no size limit" class="details-control" name="details"></textarea></div>' . "\n";
     $canonical .= '    <h4>references</h4>' . "\n";
     $canonical .= Metadata_Reference::renderReferencesArrayAsListsEdit($mds->references);
     $canonical .= '  </div>' . "\n";
     $canonical .= '  <div class="metadata-term-set-controls"><h4>' . util_lang('metadata_term_set') . "</h4>\n" . Metadata_Term_Set::renderAllAsSelectControl('', $mds->term_set ? $mds->term_set->metadata_term_set_id : 0) . "</div>\n";
     $canonical .= '  <h4>further breakdown:</h4>' . "\n";
     $canonical .= '  <ul class="metadata-structure-tree">' . "\n";
     $canonical .= '    <li><a href="' . APP_ROOT_PATH . '/app_code/metadata_structure.php?action=create&parent_metadata_structure_id=' . $mds->metadata_structure_id . '" id="btn-add-metadata-structure" title="' . htmlentities(util_lang('add_metadata_structure')) . '" class="creation_link btn">' . htmlentities(util_lang('add_metadata_structure')) . '</a></li>' . "\n";
     $children = $mds->getChildren();
     foreach ($children as $mds_child) {
         $canonical .= '    ' . $mds_child->renderAsListTreeEditable();
     }
     $canonical .= '  </ul>';
     $canonical .= '</div>';
     $rendered = $mds->renderAsEdit();
     //            echo "<pre>\n".htmlentities($canonical)."\n---------------\n".htmlentities($rendered)."\n</pre>";
     $this->assertNoPattern('/IMPLEMENTED/', $rendered);
     $this->assertEqual($canonical, $rendered);
 }
 function testDeleteStructure()
 {
     $mds_orig = Metadata_Structure::getOneFromDb(['metadata_structure_id' => 6002], $this->DB);
     $this->doLoginAdmin();
     $this->get('http://localhost/digitalfieldnotebooks/app_code/metadata_structure.php?action=delete&metadata_structure_id=' . $mds_orig->metadata_structure_id);
     //        $this->showContent();
     $this->checkBasicAsserts();
     $mds_del = Metadata_Structure::getOneFromDb(['metadata_structure_id' => 6002], $this->DB);
     $this->assertFalse($mds_del->matchesDb);
 }
 function testCanActOnTarget()
 {
     $n1 = Notebook::getOneFromDb(['notebook_id' => 1001], $this->DB);
     // owned by 101
     $n2 = Notebook::getOneFromDb(['notebook_id' => 1003], $this->DB);
     // owned by 102
     $n3 = Notebook::getOneFromDb(['notebook_id' => 1004], $this->DB);
     // owned by 110
     $np1 = Notebook_Page::getOneFromDb(['notebook_page_id' => 1101], $this->DB);
     // part of notebook 101
     $s1 = Specimen::getOneFromDb(['specimen_id' => 8001], $this->DB);
     // owned by 110
     $s2 = Specimen::getOneFromDb(['specimen_id' => 8002], $this->DB);
     // owned by 101
     $mds = Metadata_Structure::getOneFromDb(['metadata_structure_id' => 6004], $this->DB);
     $mdts = Metadata_Term_Set::getOneFromDb(['metadata_term_set_id' => 6101], $this->DB);
     $mdtv = Metadata_Term_Value::getOneFromDb(['metadata_term_value_id' => 6211], $this->DB);
     $ap = Authoritative_Plant::getOneFromDb(['authoritative_plant_id' => 5001], $this->DB);
     $actions_list = Action::getAllFromDb([], $this->DB);
     $actions = [];
     foreach ($actions_list as $act_elt) {
         $actions[$act_elt->name] = $act_elt;
     }
     // basic, field user
     $u = User::getOneFromDb(['user_id' => 101], $this->DB);
     $this->assertTrue($u->canActOnTarget($actions['view'], $n1));
     $this->assertTrue($u->canActOnTarget($actions['edit'], $n1));
     $this->assertTrue($u->canActOnTarget($actions['create'], $n1));
     $this->assertTrue($u->canActOnTarget($actions['delete'], $n1));
     $this->assertTrue($u->canActOnTarget($actions['publish'], $n1));
     $this->assertFalse($u->canActOnTarget($actions['verify'], $n1));
     $this->assertFalse($u->canActOnTarget($actions['view'], $n2));
     $this->assertFalse($u->canActOnTarget($actions['edit'], $n2));
     $this->assertTrue($u->canActOnTarget($actions['create'], $n2));
     $this->assertFalse($u->canActOnTarget($actions['delete'], $n2));
     $this->assertFalse($u->canActOnTarget($actions['publish'], $n2));
     $this->assertFalse($u->canActOnTarget($actions['verify'], $n2));
     $this->assertTrue($u->canActOnTarget($actions['view'], $n3));
     $this->assertFalse($u->canActOnTarget($actions['edit'], $n3));
     $this->assertTrue($u->canActOnTarget($actions['create'], $n3));
     $this->assertFalse($u->canActOnTarget($actions['delete'], $n3));
     $this->assertFalse($u->canActOnTarget($actions['publish'], $n3));
     $this->assertFalse($u->canActOnTarget($actions['verify'], $n3));
     $this->assertTrue($u->canActOnTarget($actions['view'], $np1));
     $this->assertTrue($u->canActOnTarget($actions['edit'], $np1));
     $this->assertTrue($u->canActOnTarget($actions['create'], $np1));
     $this->assertTrue($u->canActOnTarget($actions['delete'], $np1));
     $this->assertTrue($u->canActOnTarget($actions['publish'], $np1));
     $this->assertFalse($u->canActOnTarget($actions['verify'], $np1));
     $this->assertTrue($u->canActOnTarget($actions['view'], $s1));
     $this->assertFalse($u->canActOnTarget($actions['edit'], $s1));
     $this->assertTrue($u->canActOnTarget($actions['create'], $s1));
     $this->assertFalse($u->canActOnTarget($actions['delete'], $s1));
     $this->assertFalse($u->canActOnTarget($actions['publish'], $s1));
     $this->assertFalse($u->canActOnTarget($actions['verify'], $s1));
     $this->assertTrue($u->canActOnTarget($actions['view'], $s2));
     $this->assertTrue($u->canActOnTarget($actions['edit'], $s2));
     $this->assertTrue($u->canActOnTarget($actions['create'], $s2));
     $this->assertTrue($u->canActOnTarget($actions['delete'], $s2));
     $this->assertTrue($u->canActOnTarget($actions['publish'], $s2));
     $this->assertFalse($u->canActOnTarget($actions['verify'], $s2));
     $this->assertTrue($u->canActOnTarget($actions['view'], $mds));
     $this->assertFalse($u->canActOnTarget($actions['edit'], $mds));
     $this->assertFalse($u->canActOnTarget($actions['create'], $mds));
     $this->assertFalse($u->canActOnTarget($actions['delete'], $mds));
     $this->assertFalse($u->canActOnTarget($actions['publish'], $mds));
     $this->assertFalse($u->canActOnTarget($actions['verify'], $mds));
     $this->assertTrue($u->canActOnTarget($actions['view'], $mdts));
     $this->assertFalse($u->canActOnTarget($actions['edit'], $mdts));
     $this->assertFalse($u->canActOnTarget($actions['create'], $mdts));
     $this->assertFalse($u->canActOnTarget($actions['delete'], $mdts));
     $this->assertFalse($u->canActOnTarget($actions['publish'], $mdts));
     $this->assertFalse($u->canActOnTarget($actions['verify'], $mdts));
     $this->assertTrue($u->canActOnTarget($actions['view'], $mdtv));
     $this->assertFalse($u->canActOnTarget($actions['edit'], $mdtv));
     $this->assertFalse($u->canActOnTarget($actions['create'], $mdtv));
     $this->assertFalse($u->canActOnTarget($actions['delete'], $mdtv));
     $this->assertFalse($u->canActOnTarget($actions['publish'], $mdtv));
     $this->assertFalse($u->canActOnTarget($actions['verify'], $mdtv));
     $this->assertTrue($u->canActOnTarget($actions['view'], $ap));
     $this->assertFalse($u->canActOnTarget($actions['edit'], $ap));
     $this->assertFalse($u->canActOnTarget($actions['create'], $ap));
     $this->assertFalse($u->canActOnTarget($actions['delete'], $ap));
     $this->assertFalse($u->canActOnTarget($actions['publish'], $ap));
     $this->assertFalse($u->canActOnTarget($actions['verify'], $ap));
     // basic user on arbitrary object
     $this->assertTrue($u->canActOnTarget($actions['view'], new Authoritative_Plant(['DB' => $this->DB])));
     // system admin
     $u->flag_is_system_admin = true;
     $this->assertTrue($u->canActOnTarget($actions['view'], $n1));
     $this->assertTrue($u->canActOnTarget($actions['edit'], $n1));
     $this->assertTrue($u->canActOnTarget($actions['create'], $n1));
     $this->assertTrue($u->canActOnTarget($actions['delete'], $n1));
     $this->assertTrue($u->canActOnTarget($actions['publish'], $n1));
     $this->assertTrue($u->canActOnTarget($actions['verify'], $n1));
     $this->assertTrue($u->canActOnTarget($actions['view'], $n2));
     $this->assertTrue($u->canActOnTarget($actions['edit'], $n2));
     $this->assertTrue($u->canActOnTarget($actions['create'], $n2));
     $this->assertTrue($u->canActOnTarget($actions['delete'], $n2));
     $this->assertTrue($u->canActOnTarget($actions['publish'], $n2));
     $this->assertTrue($u->canActOnTarget($actions['verify'], $n2));
     $this->assertTrue($u->canActOnTarget($actions['view'], $n3));
     $this->assertTrue($u->canActOnTarget($actions['edit'], $n3));
     $this->assertTrue($u->canActOnTarget($actions['create'], $n3));
     $this->assertTrue($u->canActOnTarget($actions['delete'], $n3));
     $this->assertTrue($u->canActOnTarget($actions['publish'], $n3));
     $this->assertTrue($u->canActOnTarget($actions['verify'], $n3));
     $this->assertTrue($u->canActOnTarget($actions['view'], $s1));
     $this->assertTrue($u->canActOnTarget($actions['edit'], $s1));
     $this->assertTrue($u->canActOnTarget($actions['create'], $s1));
     $this->assertTrue($u->canActOnTarget($actions['delete'], $s1));
     $this->assertTrue($u->canActOnTarget($actions['publish'], $s1));
     $this->assertTrue($u->canActOnTarget($actions['verify'], $s1));
     $this->assertTrue($u->canActOnTarget($actions['view'], $s2));
     $this->assertTrue($u->canActOnTarget($actions['edit'], $s2));
     $this->assertTrue($u->canActOnTarget($actions['create'], $s2));
     $this->assertTrue($u->canActOnTarget($actions['delete'], $s2));
     $this->assertTrue($u->canActOnTarget($actions['publish'], $s2));
     $this->assertTrue($u->canActOnTarget($actions['verify'], $s2));
     $this->assertTrue($u->canActOnTarget($actions['view'], $mds));
     $this->assertTrue($u->canActOnTarget($actions['edit'], $mds));
     $this->assertTrue($u->canActOnTarget($actions['create'], $mds));
     $this->assertTrue($u->canActOnTarget($actions['delete'], $mds));
     $this->assertTrue($u->canActOnTarget($actions['publish'], $mds));
     $this->assertTrue($u->canActOnTarget($actions['verify'], $mds));
     $this->assertTrue($u->canActOnTarget($actions['view'], $mdts));
     $this->assertTrue($u->canActOnTarget($actions['edit'], $mdts));
     $this->assertTrue($u->canActOnTarget($actions['create'], $mdts));
     $this->assertTrue($u->canActOnTarget($actions['delete'], $mdts));
     $this->assertTrue($u->canActOnTarget($actions['publish'], $mdts));
     $this->assertTrue($u->canActOnTarget($actions['verify'], $mdts));
     $this->assertTrue($u->canActOnTarget($actions['view'], $mdtv));
     $this->assertTrue($u->canActOnTarget($actions['edit'], $mdtv));
     $this->assertTrue($u->canActOnTarget($actions['create'], $mdtv));
     $this->assertTrue($u->canActOnTarget($actions['delete'], $mdtv));
     $this->assertTrue($u->canActOnTarget($actions['publish'], $mdtv));
     $this->assertTrue($u->canActOnTarget($actions['verify'], $mdtv));
     $this->assertTrue($u->canActOnTarget($actions['view'], $ap));
     $this->assertTrue($u->canActOnTarget($actions['edit'], $ap));
     $this->assertTrue($u->canActOnTarget($actions['create'], $ap));
     $this->assertTrue($u->canActOnTarget($actions['delete'], $ap));
     $this->assertTrue($u->canActOnTarget($actions['publish'], $ap));
     $this->assertTrue($u->canActOnTarget($actions['verify'], $ap));
     // public user
     $u = User::getOneFromDb(['user_id' => 109], $this->DB);
     $this->assertFalse($u->canActOnTarget($actions['view'], $n1));
     $this->assertFalse($u->canActOnTarget($actions['edit'], $n1));
     $this->assertFalse($u->canActOnTarget($actions['create'], $n1));
     $this->assertFalse($u->canActOnTarget($actions['delete'], $n1));
     $this->assertFalse($u->canActOnTarget($actions['publish'], $n1));
     $this->assertFalse($u->canActOnTarget($actions['verify'], $n1));
     $this->assertFalse($u->canActOnTarget($actions['view'], $n2));
     $this->assertFalse($u->canActOnTarget($actions['edit'], $n2));
     $this->assertFalse($u->canActOnTarget($actions['create'], $n2));
     $this->assertFalse($u->canActOnTarget($actions['delete'], $n2));
     $this->assertFalse($u->canActOnTarget($actions['publish'], $n2));
     $this->assertFalse($u->canActOnTarget($actions['verify'], $n2));
     $this->assertTrue($u->canActOnTarget($actions['view'], $n3));
     $this->assertFalse($u->canActOnTarget($actions['edit'], $n3));
     $this->assertFalse($u->canActOnTarget($actions['create'], $n3));
     $this->assertFalse($u->canActOnTarget($actions['delete'], $n3));
     $this->assertFalse($u->canActOnTarget($actions['publish'], $n3));
     $this->assertFalse($u->canActOnTarget($actions['verify'], $n3));
     $this->assertTrue($u->canActOnTarget($actions['view'], $s1));
     $this->assertFalse($u->canActOnTarget($actions['edit'], $s1));
     $this->assertFalse($u->canActOnTarget($actions['create'], $s1));
     $this->assertFalse($u->canActOnTarget($actions['delete'], $s1));
     $this->assertFalse($u->canActOnTarget($actions['publish'], $s1));
     $this->assertFalse($u->canActOnTarget($actions['verify'], $s1));
     $this->assertFalse($u->canActOnTarget($actions['view'], $s2));
     $this->assertFalse($u->canActOnTarget($actions['edit'], $s2));
     $this->assertFalse($u->canActOnTarget($actions['create'], $s2));
     $this->assertFalse($u->canActOnTarget($actions['delete'], $s2));
     $this->assertFalse($u->canActOnTarget($actions['publish'], $s2));
     $this->assertFalse($u->canActOnTarget($actions['verify'], $s2));
     $this->assertTrue($u->canActOnTarget($actions['view'], $mds));
     $this->assertFalse($u->canActOnTarget($actions['edit'], $mds));
     $this->assertFalse($u->canActOnTarget($actions['create'], $mds));
     $this->assertFalse($u->canActOnTarget($actions['delete'], $mds));
     $this->assertFalse($u->canActOnTarget($actions['publish'], $mds));
     $this->assertFalse($u->canActOnTarget($actions['verify'], $mds));
     $this->assertTrue($u->canActOnTarget($actions['view'], $mdts));
     $this->assertFalse($u->canActOnTarget($actions['edit'], $mdts));
     $this->assertFalse($u->canActOnTarget($actions['create'], $mdts));
     $this->assertFalse($u->canActOnTarget($actions['delete'], $mdts));
     $this->assertFalse($u->canActOnTarget($actions['publish'], $mdts));
     $this->assertFalse($u->canActOnTarget($actions['verify'], $mdts));
     $this->assertTrue($u->canActOnTarget($actions['view'], $mdtv));
     $this->assertFalse($u->canActOnTarget($actions['edit'], $mdtv));
     $this->assertFalse($u->canActOnTarget($actions['create'], $mdtv));
     $this->assertFalse($u->canActOnTarget($actions['delete'], $mdtv));
     $this->assertFalse($u->canActOnTarget($actions['publish'], $mdtv));
     $this->assertFalse($u->canActOnTarget($actions['verify'], $mdtv));
     $this->assertTrue($u->canActOnTarget($actions['view'], $ap));
     $this->assertFalse($u->canActOnTarget($actions['edit'], $ap));
     $this->assertFalse($u->canActOnTarget($actions['create'], $ap));
     $this->assertFalse($u->canActOnTarget($actions['delete'], $ap));
     $this->assertFalse($u->canActOnTarget($actions['publish'], $ap));
     $this->assertFalse($u->canActOnTarget($actions['verify'], $ap));
     // manager
     $u = User::getOneFromDb(['user_id' => 110], $this->DB);
     // manager user
     $this->assertTrue($u->canActOnTarget($actions['view'], $n1));
     $this->assertTrue($u->canActOnTarget($actions['edit'], $n1));
     $this->assertTrue($u->canActOnTarget($actions['create'], $n1));
     $this->assertTrue($u->canActOnTarget($actions['delete'], $n1));
     $this->assertTrue($u->canActOnTarget($actions['publish'], $n1));
     $this->assertTrue($u->canActOnTarget($actions['verify'], $n1));
     $this->assertTrue($u->canActOnTarget($actions['view'], $n2));
     $this->assertTrue($u->canActOnTarget($actions['edit'], $n2));
     $this->assertTrue($u->canActOnTarget($actions['create'], $n2));
     $this->assertTrue($u->canActOnTarget($actions['delete'], $n2));
     $this->assertTrue($u->canActOnTarget($actions['publish'], $n2));
     $this->assertTrue($u->canActOnTarget($actions['verify'], $n2));
     $this->assertTrue($u->canActOnTarget($actions['view'], $n3));
     $this->assertTrue($u->canActOnTarget($actions['edit'], $n3));
     $this->assertTrue($u->canActOnTarget($actions['create'], $n3));
     $this->assertTrue($u->canActOnTarget($actions['delete'], $n3));
     $this->assertTrue($u->canActOnTarget($actions['publish'], $n3));
     $this->assertTrue($u->canActOnTarget($actions['verify'], $n3));
     $this->assertTrue($u->canActOnTarget($actions['view'], $s1));
     $this->assertTrue($u->canActOnTarget($actions['edit'], $s1));
     $this->assertTrue($u->canActOnTarget($actions['create'], $s1));
     $this->assertTrue($u->canActOnTarget($actions['delete'], $s1));
     $this->assertTrue($u->canActOnTarget($actions['publish'], $s1));
     $this->assertTrue($u->canActOnTarget($actions['verify'], $s1));
     $this->assertTrue($u->canActOnTarget($actions['view'], $s2));
     $this->assertTrue($u->canActOnTarget($actions['edit'], $s2));
     $this->assertTrue($u->canActOnTarget($actions['create'], $s2));
     $this->assertTrue($u->canActOnTarget($actions['delete'], $s2));
     $this->assertTrue($u->canActOnTarget($actions['publish'], $s2));
     $this->assertTrue($u->canActOnTarget($actions['verify'], $s2));
     $this->assertTrue($u->canActOnTarget($actions['view'], $mds));
     $this->assertTrue($u->canActOnTarget($actions['edit'], $mds));
     $this->assertTrue($u->canActOnTarget($actions['create'], $mds));
     $this->assertTrue($u->canActOnTarget($actions['delete'], $mds));
     $this->assertTrue($u->canActOnTarget($actions['publish'], $mds));
     $this->assertTrue($u->canActOnTarget($actions['verify'], $mds));
     $this->assertTrue($u->canActOnTarget($actions['view'], $mdts));
     $this->assertTrue($u->canActOnTarget($actions['edit'], $mdts));
     $this->assertTrue($u->canActOnTarget($actions['create'], $mdts));
     $this->assertTrue($u->canActOnTarget($actions['delete'], $mdts));
     $this->assertTrue($u->canActOnTarget($actions['publish'], $mdts));
     $this->assertTrue($u->canActOnTarget($actions['verify'], $mdts));
     $this->assertTrue($u->canActOnTarget($actions['view'], $mdtv));
     $this->assertTrue($u->canActOnTarget($actions['edit'], $mdtv));
     $this->assertTrue($u->canActOnTarget($actions['create'], $mdtv));
     $this->assertTrue($u->canActOnTarget($actions['delete'], $mdtv));
     $this->assertTrue($u->canActOnTarget($actions['publish'], $mdtv));
     $this->assertTrue($u->canActOnTarget($actions['verify'], $mdtv));
     $this->assertTrue($u->canActOnTarget($actions['view'], $ap));
     $this->assertTrue($u->canActOnTarget($actions['edit'], $ap));
     $this->assertTrue($u->canActOnTarget($actions['create'], $ap));
     $this->assertTrue($u->canActOnTarget($actions['delete'], $ap));
     $this->assertTrue($u->canActOnTarget($actions['publish'], $ap));
     $this->assertTrue($u->canActOnTarget($actions['verify'], $ap));
 }
 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;
 }
 public function getMetadataStructure()
 {
     return Metadata_Structure::getOneFromDb(['metadata_structure_id' => $this->label_metadata_structure_id], $this->dbConnection);
 }
 function testRenderAsView()
 {
     $mdts = Metadata_Term_Set::getOneFromDb(['metadata_term_set_id' => 6101], $this->DB);
     $mds = Metadata_Structure::getOneFromDb(['metadata_structure_id' => 6002], $this->DB);
     $canonical = '<div class="view-metadata-term-set">' . "\n";
     $canonical .= '<div class="view-metadata-term-set-header"><a href="' . APP_ROOT_PATH . '/app_code/metadata_term_set.php?action=list">' . util_lang('all_metadata_term_sets') . '</a> &gt; <h3>small lengths</h3></div>';
     $canonical .= $mdts->renderAsHtml_references();
     $canonical .= $mdts->renderAsHtml_term_values();
     //            $canonical .= '<div class="metadata-term-set-uses">';
     $canonical .= $mdts->renderAsHtml_structures();
     $canonical .= '</div>' . "\n";
     $canonical .= '</div>' . "\n";
     $rendered = $mdts->renderAsView();
     //                echo "<pre>\n".htmlentities($canonical)."\n-------\n".htmlentities($rendered)."\n</pre>";
     $this->assertNoPattern('/IMPLEMENTED/', $rendered);
     $this->assertEqual($canonical, $rendered);
     //            $this->assertPattern('/'.htmlentities($mds->name).'/',$rendered);
 }
 public function getReferrent()
 {
     if ($this->metadata_type == 'structure') {
         return Metadata_Structure::getOneFromDb(['metadata_structure_id' => $this->metadata_id, 'flag_delete' => FALSE], $this->dbConnection);
     } elseif ($this->metadata_type == 'term_set') {
         return Metadata_Term_Set::getOneFromDb(['metadata_term_set_id' => $this->metadata_id, 'flag_delete' => FALSE], $this->dbConnection);
     } elseif ($this->metadata_type == 'term_value') {
         return Metadata_Term_Value::getOneFromDb(['metadata_term_value_id' => $this->metadata_id, 'flag_delete' => FALSE], $this->dbConnection);
     } else {
         return 'UNKNOWN METADATA_TYPE: /' . $this->metadata_type . '/';
     }
 }
 function testRenderAsListItemEdit_noTermSet()
 {
     $npf = Notebook_Page_Field::getOneFromDb(['notebook_page_field_id' => 1204], $this->DB);
     $mds = Metadata_Structure::getOneFromDb(['metadata_structure_id' => 6004], $this->DB);
     global $USER;
     $USER = User::getOneFromDb(['username' => TESTINGUSER], $this->DB);
     $canonical = '<li id="list_item-notebook_page_field_1204" data-notebook_page_field_id="1204" data-created_at="' . $npf->created_at . '" data-updated_at="' . $npf->updated_at . '" data-notebook_page_id="1101" data-label_metadata_structure_id="6004" data-value_metadata_term_value_id="0" data-value_open="wavy-ish" data-flag_delete="0">' . '<div class="notebook-page-field-label field-label" title="' . htmlentities($mds->description) . '">' . $mds->renderAsFullName() . '</div> : <div class="notebook-page-field-value field-value">' . util_lang('metadata_structure_has_no_term_set') . '; <input type="text" name="page_field_open_value_1204" id="page_field_open_value_1204" class="page_field_open_value" value="wavy-ish"/>' . '</div> <button class="btn btn-danger button-mark-pagefield-for-delete" title="' . util_lang('mark_for_delete', 'ucfirst') . '" data-do-mark-title="' . util_lang('mark_for_delete', 'ucfirst') . '" data-remove-mark-title="' . util_lang('unmark_for_delete', 'ucfirst') . '" data-for_dom_id="list_item-notebook_page_field_1204" data-notebook_page_field_id="1204"><i class="icon-remove-sign icon-white"></i></button></li>';
     $rendered = $npf->renderAsListItemEdit();
     //            echo "<pre>\n".htmlentities($canonical)."\n--------\n".htmlentities($rendered)."\n</pre>";
     $this->assertEqual($canonical, $rendered);
     $this->assertNoPattern('/IMPLEMENTED/', $rendered);
 }
    }
}
if (!$has_permission) {
    $results['note'] = util_lang('no_permission');
}
# 3. branch behavior based on the action
#      create - return an appropriate form field set
if ($has_permission && $action == 'value_options') {
    $target_mds_id = 0;
    if (isset($_REQUEST['metadata_structure_id'])) {
        $target_mds_id = $_REQUEST['metadata_structure_id'];
    }
    if (!$target_mds_id) {
        $results['note'] = util_lang('msg_missing_metadata_structure');
    } else {
        $mds = Metadata_Structure::getOneFromDb(['metadata_structure_id' => $target_mds_id], $DB);
        if (!$mds->matchesDb) {
            $results['note'] = util_lang('msg_record_missing');
        } else {
            $mds->loadTermSetAndValues();
            if (!$mds->term_set) {
                $results['html_output'] = '  <option value="-1">' . util_lang('metadata_structure_has_no_term_set') . '</option>' . "\n";
            } else {
                $results['html_output'] = '  <option value="-1">' . util_lang('prompt_select') . '</option>' . "\n" . $mds->term_set->renderValuesAsOptions();
            }
            $results['status'] = 'success';
        }
    }
}
echo json_encode($results);
exit;
   public function renderAsEdit()
   {
       if ($this->metadata_structure_id != 'NEW') {
           $this->loadTermSetAndValues();
           $this->loadReferences();
       }
       //  '.$mds_parent->renderAsLink().' &gt;
       $rendered = '';
       $rendered .= '<form id="form-edit-metadata-structure-base-data" action="' . APP_ROOT_PATH . '/app_code/metadata_structure.php">' . "\n";
       $rendered .= '  <input type="hidden" name="action" value="update"/>' . "\n";
       $rendered .= '  <input type="hidden" id="metadata_structure_id" name="metadata_structure_id" value="' . $this->metadata_structure_id . '"/>' . "\n";
       $rendered .= '  <div id="actions">';
       $rendered .= '<button id="edit-submit-control" class="btn btn-success" type="submit" name="edit-submit-control" value="update"><i class="icon-ok-sign icon-white"></i> ' . util_lang($this->metadata_structure_id != 'NEW' ? 'update' : 'save', 'properize') . '</button>' . "\n";
       if ($this->metadata_structure_id != 'NEW') {
           $rendered .= '  <a id="edit-cancel-control" class="btn" href="' . APP_ROOT_PATH . '/app_code/metadata_structure.php?action=view&metadata_structure_id=' . $this->metadata_structure_id . '"><i class="icon-remove"></i> ' . util_lang('cancel', 'properize') . '</a>';
           $rendered .= '  <a id="edit-delete-metadata-structure-control" class="btn btn-danger" href="' . APP_ROOT_PATH . '/app_code/metadata_structure.php?action=delete&metadata_structure_id=' . $this->metadata_structure_id . '"><i class="icon-trash icon-white"></i> ' . util_lang('delete', 'properize') . '</a>';
       } else {
           $rendered .= '  <a id="edit-cancel-control" class="btn" href="' . APP_ROOT_PATH . '/app_code/metadata_structure.php?action=edit&metadata_structure_id=' . $this->metadata_structure_id . '"><i class="icon-remove"></i> ' . util_lang('cancel', 'properize') . '</a>';
       }
       $rendered .= '  </div>' . "\n";
       $rendered .= '<div id="edit-rendered_metadata_structure_' . $this->metadata_structure_id . '" class="edit-rendered_metadata_structure" ' . $this->fieldsAsDataAttribs() . '>
 <div class="metadata_lineage"><a href="' . APP_ROOT_PATH . '/app_code/metadata_structure.php?action=list">' . util_lang('metadata') . '</a> &gt;';
       $lineage = $this->getLineage();
       foreach ($lineage as $mds_ancestor) {
           if ($mds_ancestor->metadata_structure_id != $this->metadata_structure_id) {
               $rendered .= ' ' . $mds_ancestor->renderAsLink() . ' &gt;';
           }
       }
       $rendered .= '</div>' . "\n";
       $rendered .= '  <div class="metadata-parent-controls">' . util_lang('label_metadata_structure_change_parent') . ': ' . Metadata_Structure::renderControlSelectAllMetadataStructures('parent_metadata_structure_id', $this->parent_metadata_structure_id, util_lang('metadata_root_level')) . '</div>' . "\n";
       $rendered .= '  <div class="metadata-structure-header">' . "\n";
       $rendered .= '    <h3><input id="" class="object-name-control" type="text" name="name" value="' . htmlentities($this->name) . '"/></h3>' . "\n";
       $rendered .= '    <div class="active-state-controls"><input type="checkbox" name="flag_active" value="1"' . ($this->flag_active ? ' checked="checked"' : '') . '/> ' . util_lang('active') . '</div>' . "\n";
       $rendered .= '    <div class="description-controls"><input title="' . util_lang('title_description') . '" class="description-control" type="text" name="description" value="' . htmlentities($this->description) . '"/></div>' . "\n";
       $rendered .= '    <div class="details-controls"><textarea title="' . util_lang('title_details') . '" class="details-control" name="details">' . htmlentities($this->details) . '</textarea></div>' . "\n";
       if ($this->metadata_structure_id != 'NEW') {
           $rendered .= '    <h4>' . util_lang('metadata_references') . '</h4>' . "\n";
           $rendered .= Metadata_Reference::renderReferencesArrayAsListsEdit($this->references);
           $rendered .= '  </div>' . "\n";
       }
       $rendered .= '  <div class="metadata-term-set-controls"><h4>' . util_lang('metadata_term_set') . "</h4>\n" . Metadata_Term_Set::renderAllAsSelectControl('', $this->term_set ? $this->term_set->metadata_term_set_id : 0) . "</div>\n";
       if ($this->metadata_structure_id != 'NEW') {
           $rendered .= '  <h4>' . util_lang('metadata_children') . ':</h4>' . "\n";
           $rendered .= '  <ul class="metadata-structure-tree">' . "\n";
           $rendered .= '    <li><a href="' . APP_ROOT_PATH . '/app_code/metadata_structure.php?action=create&parent_metadata_structure_id=' . $this->metadata_structure_id . '" id="btn-add-metadata-structure" title="' . htmlentities(util_lang('add_metadata_structure')) . '" class="creation_link btn">' . htmlentities(util_lang('add_metadata_structure')) . '</a></li>' . "\n";
           $children = $this->getChildren();
           if ($children) {
               foreach ($children as $child) {
                   $rendered .= '    ' . $child->renderAsListTreeEditable();
               }
           }
           $rendered .= '  </ul>';
           if (!$this->term_set && !$children) {
               $rendered .= '<span class="empty-metadata-msg info">' . util_lang('metadata_no_children_no_values') . '</span>';
           }
       }
       $rendered .= '</div>';
       return $rendered;
   }
 public function getTargets()
 {
     switch ($this->target_type) {
         case 'global_notebook':
             return Notebook::getAllFromDb([], $this->dbConnection);
             break;
         case 'global_metadata':
             return Metadata_Structure::getAllFromDb([], $this->dbConnection);
             break;
         case 'global_plant':
             return Authoritative_Plant::getAllFromDb([], $this->dbConnection);
             break;
         case 'global_specimen':
             return Specimen::getAllFromDb([], $this->dbConnection);
             break;
         case 'notebook':
             return array(Notebook::getOneFromDb(['notebook_id' => $this->target_id], $this->dbConnection));
             break;
         case 'metadata_structure':
             return array(Metadata_Structure::getOneFromDb(['metadata_structure_id' => $this->target_id], $this->dbConnection));
             break;
         case 'plant':
             return array(Authoritative_Plant::getOneFromDb(['authoritative_id' => $this->target_id], $this->dbConnection));
             break;
         case 'specimen':
             return array(Specimen::getOneFromDb(['specimen_id' => $this->target_id], $this->dbConnection));
             break;
         default:
             return array();
     }
 }
 public function loadStructures()
 {
     $this->structures = Metadata_Structure::getAllFromDb(['metadata_term_set_id' => $this->metadata_term_set_id, 'flag_delete' => FALSE], $this->dbConnection);
     usort($this->structures, 'Metadata_Structure::cmp');
 }
        $req_key = 'new_ordering-item-metadata_structure_' . $ss->metadata_structure_id;
        //            util_prePrintR('handling '.$req_key);
        if (isset($_REQUEST[$req_key]) && is_numeric($_REQUEST[$req_key])) {
            $new_ordering = $_REQUEST[$req_key];
            if ($new_ordering != $ss->ordering) {
                $ss->ordering = $new_ordering;
                //                    $ss->matchesDb = false; // not needed because ordering field is access via -> rather than the fieldValues array
                $ss->updateDb();
            }
        }
    }
    $action = 'view';
}
if ($action == 'list') {
    echo '<h2>' . util_lang('all_metadata', 'properize') . '</h2>' . "\n";
    $all_metadata_structures = Metadata_Structure::getAllFromDb(['parent_metadata_structure_id' => 0], $DB);
    usort($all_metadata_structures, 'Metadata_Structure::cmp');
    $form_started = false;
    $available_actions = '';
    if ($USER->canActOnTarget($ACTIONS['create'], $all_metadata_structures[0])) {
        $available_actions .= '<a href="' . APP_ROOT_PATH . '/app_code/metadata_structure.php?action=create&parent_metadata_structure_id=0" id="btn-add-metadata_structure-ROOT" class="creation_link btn" title="' . htmlentities(util_lang('add_metadata_structure')) . '">' . htmlentities(util_lang('add_metadata_structure')) . '</a>';
    }
    if ($USER->canActOnTarget($ACTIONS['edit'], $all_metadata_structures[0])) {
        $available_actions .= '<button id="ordering-submit-control" class="btn btn-success" type="submit" name="ordering-submit-control" value="update_top_level_orderings"><i class="icon-ok-sign icon-white"></i> ' . util_lang('save_ordering') . '</button>' . "\n";
        echo '<form action="' . APP_ROOT_PATH . '/app_code/metadata_structure.php">' . "\n";
        echo '  <input type="hidden" name="action" value="update_top_level_orderings"/>' . "\n";
        $form_started = true;
    }
    echo '<ul class="all-metadata-structures">' . "\n";
    if ($available_actions) {
        echo '<li id="actions">' . $available_actions . '</li>' . "\n";