public static function cmp($a, $b)
 {
     if ($a->parent_metadata_structure_id == $b->parent_metadata_structure_id) {
         if ($a->ordering == $b->ordering) {
             if ($a->name == $b->name) {
                 return 0;
             }
             return $a->name < $b->name ? -1 : 1;
         }
         return $a->ordering < $b->ordering ? -1 : 1;
     }
     $lineageA = $a->getLineage();
     $lineageAIds = Db_Linked::arrayOfAttrValues($lineageA, 'metadata_structure_id');
     if (in_array($b->metadata_structure_id, $lineageAIds)) {
         // b is some kind of parent of a, therefore b comes before a, i.e. a > b
         return 1;
     }
     $lineageB = $b->getLineage();
     $lineageBIds = Db_Linked::arrayOfAttrValues($lineageB, 'metadata_structure_id');
     if (in_array($a->metadata_structure_id, $lineageBIds)) {
         // a is some kind of parent of b, therefore a comes before b, i.e. a < b
         return -1;
     }
     //            util_prePrintR($lineageA);
     //            util_prePrintR($lineageB);
     // trim off matching ancestories
     while ($lineageA[0]->metadata_structure_id == $lineageB[0]->metadata_structure_id) {
         array_shift($lineageA);
         array_shift($lineageB);
         //                util_prePrintR($lineageA);
         //                util_prePrintR($lineageB);
     }
     // return the cmp of the first descendents of the point of ancestral divergence
     return Metadata_Structure::cmp($lineageA[0], $lineageB[0]);
 }
 public function __construct($initsHash)
 {
     parent::__construct($initsHash);
     // now do custom stuff
     // e.g. automatically load all accessibility info associated with the user
     //		$this->flag_is_system_admin = false;
     //		$this->flag_is_banned = false;
 }
 public function getUsers()
 {
     $urs = User_Role::getAllFromDb(['role_id' => $this->role_id], $this->dbConnection);
     $user_ids = Db_Linked::arrayOfAttrValues($urs, 'user_id');
     $users = User::getAllFromDb(['user_id' => $user_ids], $this->dbConnection);
     usort($users, 'User::cmp');
     return $users;
 }
 public function __construct($initsHash)
 {
     parent::__construct($initsHash);
     // now do custom stuff
     // e.g. automatically load all accessibility info associated with the user
     $this->extras = array();
     $this->notebook_pages = array();
     $this->specimens = array();
 }
 public function __construct($initsHash)
 {
     parent::__construct($initsHash);
     // now do custom stuff
     // e.g. automatically load all accessibility info associated with the user
     $this->flag_workflow_published = false;
     $this->flag_workflow_validated = false;
     $this->pages = array();
 }
 public function __construct($initsHash)
 {
     parent::__construct($initsHash);
     // now do custom stuff
     // e.g. automatically load all accessibility info associated with the user
     $this->term_values = array();
     $this->references = array();
     $this->structures = array();
 }
 function testActionsMatchDatabase()
 {
     $all_db_actions = Action::getAllFromDb(['flag_delete' => FALSE], $this->DB);
     $this->assertEqual(count(Action::$VALID_ACTIONS), count($all_db_actions));
     $action_db_names = Db_Linked::arrayOfAttrValues($all_db_actions, 'name');
     foreach (Action::$VALID_ACTIONS as $va) {
         $this->assertTrue(in_array($va, $action_db_names), "'{$va}' missing from database");
     }
     foreach ($action_db_names as $db_a) {
         $this->assertTrue(in_array($db_a, Action::$VALID_ACTIONS), "'{$db_a}' missing from VALID_ACTIONS");
     }
 }
 public function doDelete($debug = 0)
 {
     $origFile = $_SERVER['DOCUMENT_ROOT'] . APP_ROOT_PATH . '/image_data/specimen/' . $this->image_reference;
     if (file_exists($origFile)) {
         if (rename($origFile, $origFile . '.DEL')) {
             parent::doDelete($debug);
         }
     } else {
         parent::doDelete($debug);
     }
 }
 function doDelete($debug = 0)
 {
     $this->cacheImages();
     foreach ($this->images as $img) {
         $img->doDelete($debug);
     }
     parent::doDelete($debug);
 }
 public function getAccessibleNotebooks($for_action, $debug_flag = 0)
 {
     if ($this->flag_is_system_admin) {
         if ($debug_flag) {
             echo "user is system admin<br/>\n";
         }
         return Notebook::getAllFromDb(['flag_delete' => FALSE], $this->dbConnection);
     }
     if (is_string($for_action)) {
         global $ACTIONS;
         $for_action = $ACTIONS[$for_action];
     }
     //util_prePrintR($this);
     $accessible_notebooks_ids = array();
     if ($for_action->name == 'view' || $for_action->name == 'list') {
         $all_notebooks = Notebook::getAllFromDb(['flag_workflow_published' => TRUE, 'flag_workflow_validated' => TRUE, 'flag_delete' => FALSE], $this->dbConnection);
         $accessible_notebooks_ids = Db_Linked::arrayOfAttrValues($all_notebooks, 'notebook_id');
     }
     $roles = $this->getRoles();
     if ($debug_flag) {
         echo "user roles are<br/>\n";
         util_prePrintR($roles);
     }
     foreach (Db_Linked::arrayOfAttrValues($roles, 'role_id') as $role_id) {
         $global_check = Role_Action_Target::getAllFromDb(['role_id' => $role_id, 'action_id' => $for_action->action_id, 'target_type' => 'global_notebook'], $this->dbConnection);
         if ($debug_flag) {
             echo "global_check is <br/>\n";
             util_prePrintR($global_check);
         }
         if (count($global_check) > 0) {
             $all_notebooks = Notebook::getAllFromDb(['flag_delete' => FALSE], $this->dbConnection);
             $accessible_notebooks_ids = Db_Linked::arrayOfAttrValues($all_notebooks, 'notebook_id');
         }
         $role_action_targets = Role_Action_Target::getAllFromDb(['role_id' => $role_id, 'action_id' => $for_action->action_id, 'target_type' => 'notebook'], $this->dbConnection);
         foreach ($role_action_targets as $rat) {
             if (!in_array($rat->target_id, $accessible_notebooks_ids)) {
                 $accessible_notebooks_ids[] = $rat->target_id;
             }
         }
     }
     //            util_prePrintR($accessible_notebooks_ids);
     $owned_notebooks = Notebook::getAllFromDb(['user_id' => $this->user_id], $this->dbConnection);
     $owned_notebook_ids = Db_Linked::arrayOfAttrValues($owned_notebooks, 'notebook_id');
     $additional_notebook_ids = array();
     foreach ($accessible_notebooks_ids as $an_id) {
         if (!in_array($an_id, $owned_notebook_ids)) {
             $additional_notebook_ids[] = $an_id;
         }
     }
     $additional_notebooks = array();
     if (count($additional_notebook_ids) > 0) {
         $additional_notebooks = Notebook::getAllFromDb(['notebook_id' => $additional_notebook_ids], $this->dbConnection);
     }
     $ret = array_merge($owned_notebooks, $additional_notebooks);
     //            util_prePrintR($accessible_notebooks_ids);
     return $ret;
 }
 public static function buildFetchSql(&$identHash)
 {
     //echo "build sql start\n";
     //		print_r($identHash);
     $all_fields = static::$fields;
     $use_fields = array();
     foreach ($all_fields as $field_name) {
         array_push($use_fields, Db_Linked::sanitizeFieldName($field_name));
     }
     $fetchSql = 'SELECT ' . implode(',', $use_fields) . ' FROM ' . static::$dbTable . ' WHERE 1=1';
     $keys_to_remove = [];
     $key_vals_to_add = [];
     $param_keys_counters = [];
     foreach ($identHash as $k => $v) {
         if (is_array($v)) {
             if (count($v) <= 0) {
                 trigger_error(Db_Linked::$ERR_MSG_BAD_SEARCH_PARAM, E_USER_ERROR);
                 return;
             }
             array_push($keys_to_remove, $k);
             $fetchSql .= ' AND ' . Db_Linked::sanitizeFieldName($k) . ' IN (';
             for ($i = 0, $numElts = count($v); $i < $numElts; $i++) {
                 $newKey = "__{$k}{$i}";
                 $key_use_counter = 1;
                 if (array_key_exists($newKey, $param_keys_counters)) {
                     $key_use_counter = $param_keys_counters[$newKey] + 1;
                     $newKey = $newKey . '__' . $key_use_counter;
                 }
                 $param_keys_counters["__{$k}{$i}"] = $key_use_counter;
                 $key_vals_to_add[$newKey] = $v[$i];
                 if ($i > 0) {
                     $fetchSql .= ',';
                 }
                 $fetchSql .= ":{$newKey}";
             }
             $fetchSql .= ')';
         } else {
             $k_parts = preg_split('/\\s+/', $k);
             $num_k_parts = count($k_parts);
             if ($num_k_parts == 1) {
                 # handle repeated use of same field in the query
                 $newKey = $k;
                 $key_use_counter = 1;
                 if (array_key_exists($newKey, $param_keys_counters)) {
                     $key_use_counter = $param_keys_counters[$newKey] + 1;
                     $newKey = $newKey . '__' . $key_use_counter;
                     $key_vals_to_add[$newKey] = $v;
                     array_push($keys_to_remove, $k);
                 }
                 $param_keys_counters[$k] = $key_use_counter;
                 $fetchSql .= ' AND ' . Db_Linked::sanitizeFieldName($k) . ' = :' . $newKey;
             } else {
                 $k_comp = strtoupper(implode(' ', array_slice($k_parts, 1, $num_k_parts - 1)));
                 $valid_comps = ['<', '<=', '>', '>=', '!=', 'LIKE', 'NOT LIKE', 'IS NULL', 'IS NOT NULL'];
                 if (in_array($k_comp, $valid_comps)) {
                     array_push($keys_to_remove, $k);
                     if ($k_comp == 'IS NULL' || $k_comp == 'IS NOT NULL') {
                         $fetchSql .= ' AND ' . $k_parts[0] . ' ' . $k_comp;
                     } else {
                         $k_field = $k_parts[0];
                         $newKey = $k_field;
                         # handle repeated use of same field in the query
                         $key_use_counter = 1;
                         if (array_key_exists($newKey, $param_keys_counters)) {
                             $key_use_counter = $param_keys_counters[$newKey] + 1;
                             $newKey = $newKey . '__' . $key_use_counter;
                             $key_vals_to_add[$newKey] = $v;
                             array_push($keys_to_remove, $k);
                         }
                         $param_keys_counters[$k_field] = $key_use_counter;
                         $key_vals_to_add[$newKey] = $v;
                         $fetchSql .= ' AND ' . Db_Linked::sanitizeFieldName($k_field) . ' ' . $k_comp . ' :' . $newKey;
                     }
                 }
             }
         }
     }
     foreach ($keys_to_remove as $k) {
         unset($identHash[$k]);
     }
     foreach ($key_vals_to_add as $k => $v) {
         $identHash[$k] = $v;
     }
     $newIdent = [];
     foreach ($identHash as $k => $v) {
         $newIdent[":{$k}"] = $v;
     }
     $identHash = $newIdent;
     //echo "build sql end\n";
     //		print_r($identHash);
     return $fetchSql;
 }
 function testSanitizeFieldName()
 {
     $f = 'order';
     $this->assertEqual('`order`', Db_Linked::sanitizeFieldName($f));
 }
 public function doDelete($debug = 0)
 {
     $this->loadPageFields();
     $this->loadSpecimens();
     foreach ($this->page_fields as $pf) {
         $pf->doDelete($debug);
     }
     foreach ($this->specimens as $s) {
         $s->doDelete($debug);
     }
     parent::doDelete($debug);
 }
 public function renderAsOption($flag_is_selected = false)
 {
     $this->cacheReferences();
     $rendered = '<option data-metadata_term_value_id="' . $this->metadata_term_value_id . '" data-description="' . htmlentities($this->description) . '" data-ARRAY_metadata_reference_ids="' . implode(',', Db_Linked::arrayOfAttrValues($this->references, 'metadata_reference_id')) . '" title="' . htmlentities($this->description) . '" value="' . $this->metadata_term_value_id . '"' . ($flag_is_selected ? ' selected="selected"' : '') . '>' . htmlentities($this->name) . '</option>';
     return $rendered;
 }
 function testRenderAsOption()
 {
     // $flag_selected
     //            $this->todo();
     $mdtv = Metadata_Term_Value::getOneFromDb(['metadata_term_value_id' => 6210], $this->DB);
     $mdtv->loadReferences();
     //--------------------------
     $canonical_not_selected = '<option data-metadata_term_value_id="' . $mdtv->metadata_term_value_id . '" data-description="' . htmlentities($mdtv->description) . '" data-ARRAY_metadata_reference_ids="' . implode(',', Db_Linked::arrayOfAttrValues($mdtv->references, 'metadata_reference_id')) . '" title="' . htmlentities($mdtv->description) . '" value="' . $mdtv->metadata_term_value_id . '">' . htmlentities($mdtv->name) . '</option>';
     $rendered = $mdtv->renderAsOption();
     //            echo "<pre>\n".htmlentities($canonical_not_selected)."\n-------\n".htmlentities($rendered)."\n</pre>";
     $this->assertEqual($canonical_not_selected, $rendered);
     $this->assertNoPattern('/IMPLEMENTED/', $rendered);
     //--------------------------
     $canonical_selected = '<option data-metadata_term_value_id="' . $mdtv->metadata_term_value_id . '" data-description="' . htmlentities($mdtv->description) . '" data-ARRAY_metadata_reference_ids="' . implode(',', Db_Linked::arrayOfAttrValues($mdtv->references, 'metadata_reference_id')) . '" title="' . htmlentities($mdtv->description) . '" value="' . $mdtv->metadata_term_value_id . '" selected="selected">' . htmlentities($mdtv->name) . '</option>';
     $rendered = $mdtv->renderAsOption(true);
     //            echo "<pre>\n".htmlentities($canonical_selected)."\n-------\n".htmlentities($rendered)."\n</pre>";
     $this->assertEqual($canonical_selected, $rendered);
     $this->assertNoPattern('/IMPLEMENTED/', $rendered);
 }
    function testRenderAsEdit_owner()
    {
        //            $this->todo();
        $np = Notebook_Page::getOneFromDb(['notebook_page_id' => 1101], $this->DB);
        $np->loadPageFields();
        $np->loadSpecimens();
        $n = $np->getNotebook();
        $ap = $np->getAuthoritativePlant();
        global $USER, $DB;
        $USER = User::getOneFromDb(['username' => TESTINGUSER], $this->DB);
        $DB = $this->DB;
        //            $this->todo('add canonical code for how to handle authoritative plant selection');
        //            <h3 class="notebook_page_title">'.$n->renderAsLink().': '.$ap->renderAsShortText().'</h3>
        $canonical = '<div id="rendered_notebook_page_1101" class="rendered_notebook_page edit_rendered_notebook_page" ' . $np->fieldsAsDataAttribs() . ' data-can-edit="1">
<form id="form-edit-notebook-page-base-data" action="' . APP_ROOT_PATH . '/app_code/notebook_page.php">
  <input type="hidden" name="action" value="update"/>
  <input type="hidden" id="notebook_page_id" name="notebook_page_id" value="' . $np->notebook_page_id . '"/>
  <input type="hidden" id="notebook_id" name="notebook_id" value="1001"/>
  <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>
  <a id="edit-cancel-control" class="btn" href="/digitalfieldnotebooks/app_code/notebook_page.php?action=view&notebook_page_id=1101"><i class="icon-remove"></i> Cancel</a>  <a id="edit-delete-notebook-page-control" class="btn btn-danger" href="/digitalfieldnotebooks/app_code/notebook_page.php?action=delete&notebook_page_id=1101"><i class="icon-trash icon-white"></i> Delete</a></div>
<h4>' . util_lang('page_in_notebook', 'ucfirst') . ' <a href="' . APP_ROOT_PATH . '/app_code/notebook.php?action=view&notebook_id=' . $n->notebook_id . '" id="parent-notebook-link">' . htmlentities($n->name) . '</a></h4>
<a class="show-hide-control" href="#" data-for_elt_id="select_new_authoritative_plant_1101">select or change the plant</a>  <div id="select_new_authoritative_plant_1101" class="select_new_authoritative_plant">' . Authoritative_Plant::renderControlSelectAllAuthoritativePlants($ap->authoritative_plant_id) . '</div>
  ' . $ap->renderAsViewEmbed() . '
  <div class="info-timestamps"><span class="created_at">' . util_lang('created_at') . ' ' . util_datetimeFormatted($np->created_at) . '</span>, <span class="updated_at">' . util_lang('updated_at') . ' ' . util_datetimeFormatted($np->updated_at) . '</span></div>
  <div class="info-owner">' . util_lang('owned_by') . ' <a href="' . APP_ROOT_PATH . '/app_code/user.php?action=view&user_id=101">' . htmlentities($USER->screen_name) . '</a></div>
<div class="control-workflows">  <span class="published_state workflow-control"><input id="notebook-page-workflow-publish-control" type="checkbox" name="flag_workflow_published" value="1" /> ' . util_lang('publish') . '</span>, <span class="verified_state verified_state_false workflow-info">' . util_lang('verified_false') . '</span><br/>
</div>
  <div class="notebook_page_notes"><textarea id="notebook-page-notes" name="notes" rows="4" cols="120">testing notebook page the first in testnotebook1, owned by user 101</textarea></div>
  <h4>' . ucfirst(util_lang('metadata')) . '</h4>
  <ul class="notebook-page-fields">
';
        $canonical .= '    <li><a href="#" id="add_new_notebook_page_field_button" class="btn">' . util_lang('add_notebook_page_field') . '</a></li>' . "\n";
        if ($np->page_fields) {
            $prev_pf_structure_id = $np->page_fields[0]->label_metadata_structure_id;
            foreach ($np->page_fields as $pf) {
                $spacer_class = '';
                if ($pf->label_metadata_structure_id != $prev_pf_structure_id) {
                    $spacer_class = 'spacing-list-item';
                }
                $canonical .= '    ' . $pf->renderAsListItemEdit('list_item-notebook_page_field_' . $pf->notebook_page_field_id, [$spacer_class]) . "\n";
                $prev_pf_structure_id = $pf->label_metadata_structure_id;
            }
        } else {
            $canonical .= '<li>' . util_lang('no_metadata', 'ucfirst') . '</li>' . "\n";
        }
        $canonical .= '  </ul>
  <h4>' . ucfirst(util_lang('specimens')) . '</h4>
  <ul class="specimens">
';
        //            $this->todo('refine canonical code for new page specimen');
        $canonical .= '    <li><a href="#" id="add_new_specimen_button" class="btn">' . util_lang('add_specimen') . '</a></li>' . "\n";
        foreach ($np->specimens as $specimen) {
            $canonical .= '    <li id="list_item-specimen_' . $specimen->specimen_id . '">' . $specimen->renderAsEditEmbed() . "</li>\n";
        }
        $canonical .= '  </ul>' . "\n";
        $canonical .= '<input type="hidden" id="initial_page_field_ids" name="initial_page_field_ids" value="' . implode(',', Db_Linked::arrayOfAttrValues($np->page_fields, 'notebook_page_field_id')) . '"/>' . "\n";
        $canonical .= '<input type="hidden" id="created_page_field_ids" name="created_page_field_ids" value=""/>' . "\n";
        $canonical .= '<input type="hidden" id="deleted_page_field_ids" name="deleted_page_field_ids" value=""/>' . "\n";
        $canonical .= '<input type="hidden" id="initial_specimen_ids" name="initial_specimen_ids" value="' . implode(',', Db_Linked::arrayOfAttrValues($np->specimens, 'specimen_id')) . '"/>' . "\n";
        $canonical .= '<input type="hidden" id="created_specimen_ids" name="created_specimen_ids" value=""/>' . "\n";
        $canonical .= '<input type="hidden" id="deleted_specimen_ids" name="deleted_specimen_ids" value=""/>' . "\n";
        $canonical .= '</form>
</div>';
        $rendered = $np->renderAsEdit();
        //            echo "<pre>
        //-----------
        //".htmlentities($canonical)."
        //-----------
        //".htmlentities($rendered)."
        //-----------
        //</pre>";
        $this->assertEqual($canonical, $rendered);
        $this->assertNoPattern('/IMPLEMENTED/', $rendered);
    }