<commit_before><?php
namespace php_active_record;

class TaxonConcept extends ActiveRecord
{
    public static $has_many = array(
            array('hierarchy_entries'),
            array('hierarchies', 'through' => 'hierarchy_entries'),
            array('names', 'through' => 'hierarchy_entries'),
            array('ranks', 'through' => 'hierarchy_entries')
        );
    
    function supercede($taxon_concept_id)
    {
        self::supercede_by_ids($taxon_concept_id, $this->id);
    }
    
    public static function supercede_by_ids($id1, $id2, $update_caches = false)
    {
        if($id1 == $id2) return true;
        if(!$id1 || !$id2) return false;
        $id1 = TaxonConcept::get_superceded_by($id1);
        $id2 = TaxonConcept::get_superceded_by($id2);
        
        // always replace the larger ID with the smaller one
        if($id2 < $id1) list($id1, $id2) = array($id2, $id1);
        
        $mysqli =& $GLOBALS['mysqli_connection'];
        
        // at this point ID2 is the one going away
        // ID2 is being superceded by ID1
        $mysqli->update("UPDATE hierarchy_entries he JOIN taxon_concepts tc ON (he.taxon_concept_id=tc.id) SET he.taxon_concept_id=$id1, tc.supercedure_id=$id1 WHERE taxon_concept_id=$id2");
        
        // updating TCN => all names linked to ID2 are getting linked to ID1
        $mysqli->update("UPDATE IGNORE users_data_objects SET taxon_concept_id=$id1 WHERE taxon_concept_id=$id2");
        $mysqli->update("UPDATE IGNORE taxon_concept_names SET taxon_concept_id=$id1 WHERE taxon_concept_id=$id2");
        $mysqli->update("DELETE FROM taxon_concept_names WHERE taxon_concept_id=$id2");
        $mysqli->update("UPDATE IGNORE data_objects_taxon_concepts SET taxon_concept_id=$id1 WHERE taxon_concept_id=$id2");
        $mysqli->update("DELETE FROM data_objects_taxon_concepts WHERE taxon_concept_id=$id2");
        $mysqli->update("UPDATE IGNORE hierarchy_entries he JOIN random_hierarchy_images rhi ON (he.id=rhi.hierarchy_entry_id) SET rhi.taxon_concept_id=he.taxon_concept_id WHERE he.taxon_concept_id=$id2");
        $mysqli->update("UPDATE IGNORE taxon_concepts_flattened SET taxon_concept_id=$id1 WHERE taxon_concept_id=$id2");
        $mysqli->update("DELETE FROM taxon_concepts_flattened WHERE taxon_concept_id=$id2");
        $mysqli->update("UPDATE IGNORE taxon_concepts_flattened SET ancestor_id=$id1 WHERE ancestor_id=$id2");
        $mysqli->update("DELETE FROM taxon_concepts_flattened WHERE ancestor_id=$id2");
        $mysqli->update("UPDATE IGNORE collection_items SET object_id=$id1 WHERE object_id=$id2 AND object_type='TaxonConcept'");
            
        if($update_caches)
        {
            // DO THE SOLR STUFF HERE, HIERARCHICAL
            // all descendants' DataObject
            // all descendants' objects in SiteSearch
            // each concept in SiteSearch
            // CollectionItems?
            self::reindex_descendants_objects($id1);
            self::reindex_descendants_objects($id2);
            self::reindex_descendants($id1);
            self::reindex_descendants($id2);
            self::reindex_collection_items($id1);
        }
        $solr = new SolrAPI(SOLR_SERVER, 'collection_items');
        $solr->delete("object_type:TaxonConcept AND object_id:$id2");
        $mysqli->update("DELETE FROM collection_items WHERE object_id=$id2 AND object_type='TaxonConcept'");
    }
    
    public static function reindex_descendants_objects($taxon_concept_id)
    {
        $data_object_ids = Tasks::get_descendant_objects($taxon_concept_id);
        if($data_object_ids)
        {
            $object_indexer = new DataObjectAncestriesIndexer();
            $object_indexer->index_objects($data_object_ids);

            $search_indexer = new SiteSearchIndexer();
            $search_indexer->index_type('DataObject', 'data_objects', 'lookup_objects', $data_object_ids);
        }
    }
    
    public static function count_descendants_objects($taxon_concept_id)<commit_msg>Making sure collection items are in sync with merges<commit_after><?php
namespace php_active_record;

class TaxonConcept extends ActiveRecord
{
    public static $has_many = array(
            array('hierarchy_entries'),
            array('hierarchies', 'through' => 'hierarchy_entries'),
            array('names', 'through' => 'hierarchy_entries'),
            array('ranks', 'through' => 'hierarchy_entries')
        );
    
    function supercede($taxon_concept_id)
    {
        self::supercede_by_ids($taxon_concept_id, $this->id);
    }
    
    public static function supercede_by_ids($id1, $id2, $update_caches = false)
    {
        if($id1 == $id2) return true;
        if(!$id1 || !$id2) return false;
        $id1 = TaxonConcept::get_superceded_by($id1);
        $id2 = TaxonConcept::get_superceded_by($id2);
        
        // always replace the larger ID with the smaller one
        if($id2 < $id1) list($id1, $id2) = array($id2, $id1);
        
        $mysqli =& $GLOBALS['mysqli_connection'];
        
        // at this point ID2 is the one going away
        // ID2 is being superceded by ID1
        $mysqli->update("UPDATE hierarchy_entries he JOIN taxon_concepts tc ON (he.taxon_concept_id=tc.id) SET he.taxon_concept_id=$id1, tc.supercedure_id=$id1 WHERE taxon_concept_id=$id2");
        
        // updating TCN => all names linked to ID2 are getting linked to ID1
        $mysqli->update("UPDATE IGNORE users_data_objects SET taxon_concept_id=$id1 WHERE taxon_concept_id=$id2");
        $mysqli->update("UPDATE IGNORE taxon_concept_names SET taxon_concept_id=$id1 WHERE taxon_concept_id=$id2");
        $mysqli->update("DELETE FROM taxon_concept_names WHERE taxon_concept_id=$id2");
        $mysqli->update("UPDATE IGNORE data_objects_taxon_concepts SET taxon_concept_id=$id1 WHERE taxon_concept_id=$id2");
        $mysqli->update("DELETE FROM data_objects_taxon_concepts WHERE taxon_concept_id=$id2");
        $mysqli->update("UPDATE IGNORE hierarchy_entries he JOIN random_hierarchy_images rhi ON (he.id=rhi.hierarchy_entry_id) SET rhi.taxon_concept_id=he.taxon_concept_id WHERE he.taxon_concept_id=$id2");
        $mysqli->update("UPDATE IGNORE taxon_concepts_flattened SET taxon_concept_id=$id1 WHERE taxon_concept_id=$id2");
        $mysqli->update("DELETE FROM taxon_concepts_flattened WHERE taxon_concept_id=$id2");
        $mysqli->update("UPDATE IGNORE taxon_concepts_flattened SET ancestor_id=$id1 WHERE ancestor_id=$id2");
        $mysqli->update("DELETE FROM taxon_concepts_flattened WHERE ancestor_id=$id2");
        $mysqli->update("UPDATE IGNORE collection_items SET object_id=$id1 WHERE object_id=$id2 AND object_type='TaxonConcept'");
        self::reindex_collection_items($id1);
        
        if($update_caches)
        {
            // DO THE SOLR STUFF HERE, HIERARCHICAL
            // all descendants' DataObject
            // all descendants' objects in SiteSearch
            // each concept in SiteSearch
            // CollectionItems?
            self::reindex_descendants_objects($id1);
            self::reindex_descendants_objects($id2);
            self::reindex_descendants($id1);
            self::reindex_descendants($id2);
        }
        $solr = new SolrAPI(SOLR_SERVER, 'collection_items');
        $solr->delete("object_type:TaxonConcept AND object_id:$id2");
        $mysqli->update("DELETE FROM collection_items WHERE object_id=$id2 AND object_type='TaxonConcept'");
    }
    
    public static function reindex_descendants_objects($taxon_concept_id)
    {
        $data_object_ids = Tasks::get_descendant_objects($taxon_concept_id);
        if($data_object_ids)
        {
            $object_indexer = new DataObjectAncestriesIndexer();
            $object_indexer->index_objects($data_object_ids);

            $search_indexer = new SiteSearchIndexer();
            $search_indexer->index_type('DataObject', 'data_objects', 'lookup_objects', $data_object_ids);
        }
    }
    
    public static function count_descendants_objects($taxon_concept_id)
{'fraction_non_alphanumeric': 0.10857925538538164, 'fraction_numerical': 0.011953679491968622, 'mean_word_length': 3.3486735246345427, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 45, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '214537', 'n_tokens_mistral': 2663, 'n_tokens_neox': 2548, 'n_words': 485}