If a function requires add_action(‘init’) how can I run it only once on plugin activation?

I am using wp_insert_term() to insert a large number of taxonomy terms from a csv file. The contents of that csv file might change occasionally. According to the codex, wp_insert_term() needs to run on add_action(‘init’) but I only want to run it once. How can I achieve that on plugin activation?

I am currently just doing this in my plugin’s constructor which runs on every page load:

Read More
   add_action('init', array($this, 'add_geo_terms'));

and then

public function add_geo_terms() {


    $path = plugin_dir_path( __FILE__ ).'assets/uk-counties.csv';
    $row = 1;
    if (($handle = fopen($path, "r")) !== FALSE) {
        while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
            $num = count($data);
            $row++;
            for ($c=0; $c < $num; $c++) {
                if ($c == 1) {
                    error_log( $data[$c] . "<br />n");
                    wp_insert_term($data[$c],'reseller-regions');
                }
            }
        }
        fclose($handle);
    }
}

I am using the activation functions provided by the wordpress plugin boilerplate so I don’t believe this is really a duplicate.

register_activation_hook( __FILE__, array( 'WPS_RESELLER', 'activate' ) );


public static function activate( $network_wide ) {
        if ( function_exists( 'is_multisite' ) && is_multisite() ) {
            if ( $network_wide  ) {
                // Get all blog ids
                $blog_ids = self::get_blog_ids();

                foreach ( $blog_ids as $blog_id ) {
                    switch_to_blog( $blog_id );
                    self::single_activate();
                }
                restore_current_blog();
            } else {
                self::single_activate();
            }
        } else {
            self::single_activate();
        }
    }

private static function single_activate() {
    add_action('init', 'add_partner_terms'); // i have tried many variations with classname, self etc
    add_action('init', 'add_geo_terms');

}

Related posts

3 comments

  1. I don’t think there is a need to add the items to the init hook from the activation function. I think you can call them directly:

    private static function single_activate() {
        self::add_partner_terms(); //$this->add_partner_terms();
        self::add_geo_terms();  //$this->add_geo_terms();
    }
    

    I’m not really sure if it should be self:: or $this-> because I’m a little bit fuzzy about OOP, especially tonight.

  2. The codex is mistaken. Or rather, was mistaken. wp_insert_term can be run at any opportune moment.

    You should not run it before init, but there is no particular need to run it on init.

    Remember, the codex is a wiki. People can edit it freely. Not all of them are going to be 100% every time.

    Edit: As for the reason your code in the question doesn’t work: The “init” action does not run during the activation process. So adding those two actions won’t do anything. You can instead put the insert term directly in that single_activate function and it’ll be fine. However, be sure to check whether the term you want to insert exists or not first. People can activate, deactivate, and re-activate too.

Comments are closed.