public static function cmp($a, $b)
 {
     if (Specimen::$SORT_PRIORITIES_FOR_LINK_TO_TYPES[$a->link_to_type] == Specimen::$SORT_PRIORITIES_FOR_LINK_TO_TYPES[$b->link_to_type]) {
         if ($a->user_id == $b->user_id) {
             if ($a->link_to_id == $b->link_to_id) {
                 if ($a->ordering == $b->ordering) {
                     if ($a->name == $b->name) {
                         if ($a->catalog_identifier == $b->catalog_identifier) {
                             return 0;
                         }
                         return $a->catalog_identifier < $b->catalog_identifier ? -1 : 1;
                     }
                     return $a->name < $b->name ? -1 : 1;
                 }
                 return $a->ordering < $b->ordering ? -1 : 1;
             }
             if ($a->link_to_type == 'authoritative_plant') {
                 return Authoritative_Plant::cmp($a->getLinked(), $b->getLinked());
             }
             if ($a->link_to_type == 'notebook_page') {
                 return Notebook_Page::cmp($a->getLinked(), $b->getLinked());
             }
             return 0;
         }
         return User::cmp($a->getUser(), $b->getUser());
     }
     return Specimen::$SORT_PRIORITIES_FOR_LINK_TO_TYPES[$a->link_to_type] < Specimen::$SORT_PRIORITIES_FOR_LINK_TO_TYPES[$b->link_to_type] ? -1 : 1;
 }
 public static function cmp($a, $b)
 {
     if ($a->notebook_id == $b->notebook_id) {
         //                echo "auth plant cmp";
         return Authoritative_Plant::cmp($a->getAuthoritativePlant(), $b->getAuthoritativePlant());
     }
     //            echo "notebook cmp";
     return Notebook::cmp($a->getNotebook(), $b->getNotebook());
 }
 function testCmpExtended()
 {
     $p1 = Authoritative_Plant::getOneFromDb(['authoritative_plant_id' => 5001], $this->DB);
     $p2 = Authoritative_Plant::getOneFromDb(['authoritative_plant_id' => 5002], $this->DB);
     $this->assertEqual(Authoritative_Plant::cmp($p1, $p2), -1);
     $this->assertEqual(Authoritative_Plant::cmp($p1, $p1), 0);
     $this->assertEqual(Authoritative_Plant::cmp($p2, $p1), 1);
     $ps = Authoritative_Plant::getAllFromDb([], $this->DB);
     usort($ps, 'Authoritative_Plant::cmpExtended');
     $this->assertEqual('AP_1_CI', $ps[0]->catalog_identifier);
     $this->assertEqual('AP_2_CI', $ps[1]->catalog_identifier);
     $this->assertEqual('AP_3_CI', $ps[2]->catalog_identifier);
     $this->assertEqual('AP_4_CI', $ps[3]->catalog_identifier);
     $this->assertEqual('AP_5_CI', $ps[4]->catalog_identifier);
     $this->assertEqual('AP_6_CI', $ps[5]->catalog_identifier);
     $this->assertEqual('AP_7_CI', $ps[6]->catalog_identifier);
     $this->assertEqual('AP_8_CI', $ps[7]->catalog_identifier);
 }
 public static function cmp($a, $b)
 {
     // role, then action, then type, then target
     if ($a->role_id == $b->role_id) {
         if ($a->action_id == $b->action_id) {
             if (Role_Action_Target::$SORT_PRIORITIES_FOR_TYPES[$a->target_type] == Role_Action_Target::$SORT_PRIORITIES_FOR_TYPES[$b->target_type]) {
                 if ($a->target_id == $b->target_id) {
                     return 0;
                 }
                 if ($a->target_id == 0) {
                     return -1;
                 }
                 if ($b->target_id == 0) {
                     return 1;
                 }
                 switch ($a->target_type) {
                     case 'notebook':
                         return Notebook::cmp($a->getTargets()[0], $b->getTargets()[0]);
                         break;
                     case 'metadata_structure':
                         return Metadata_Structure::cmp($a->getTargets()[0], $b->getTargets()[0]);
                         break;
                     case 'plant':
                         return Authoritative_Plant::cmp($a->getTargets()[0], $b->getTargets()[0]);
                         break;
                     case 'specimen':
                         return Specimen::cmp($a->getTargets()[0], $b->getTargets()[0]);
                         break;
                     default:
                         return 0;
                 }
             }
             return Role_Action_Target::$SORT_PRIORITIES_FOR_TYPES[$a->target_type] < Role_Action_Target::$SORT_PRIORITIES_FOR_TYPES[$b->target_type] ? -1 : 1;
         }
         return Action::cmp($a->getAction(), $b->getAction());
     }
     return Role::cmp($a->getRole(), $b->getRole());
 }