Updating Search Index on Plugin Upgrade

I’m adding search to an existing plugin and would like to have it index the custom records types at the time of the upgrade. I’ve already got the search working for records that have been re-saved (i.e. using Mixin_Search and after_save), but wonder how I might create a new job/process that fires the search indexing on upgrade, e.g.

public function hookUpgrade($args)
{
        $oldVersion = $args['old_version'];
        $newVersion = $args['new_version'];
        if($oldVersion < 1.6){
                /* INDEX EXISTING PLUGIN RECORDS... */
        }
}

Firing off a search index job is actually pretty easy. You should take a look at how the search settings page does it.

Note that that’s going to be a full reindex. You could do just your type of record also, but you’d need a slightly different job to actually do that: the default one does all records enabled for search.

I think maybe I have something else going on. Anytime I reindex, it only indexes the Items and Files. None of the other plugin records (including Simple Pages) get indexed unless I re-save them and they are removed from the previous results.

@jflatnes I’m starting a new thread for the plugin search index issue noted above.

I’m going to post some truncated code below and hope you can help me see what I’m missing in terms of adding search to a plugin record.

In my plugin class…

    protected $_filters = array(
		//...
		'search_record_types',	
		);
    protected $_hooks = array(
        //...
        'upgrade',
	);

    //...

    public function hookUpgrade($args)
    {
        $oldVersion = $args['old_version'];
        $newVersion = $args['new_version'];
        //...
	    if($oldVersion < '1.6'){
			Zend_Registry::get('bootstrap')->getResource('jobs')->sendLongRunning('Job_SearchTextIndex');
	    }
	}

    //...

    public function filterSearchRecordTypes($recordTypes){
	    $recordTypes['Tour'] = __('Tour');
	    return $recordTypes;		
	}

In my custom record model…

    public function _initializeMixins()
    {
        $this->_mixins[] = new Mixin_Search($this);
    }

    //...

    protected function afterSave($args)
    {
        if (!$this->public) {
            $this->setSearchTextPrivate();
        }
        $this->setSearchTextTitle($this->title);
        $this->addSearchText($this->title);
        $this->addSearchText($this->description);
    }

Are you sure it’s that plugin causing the error?

At least what you’ve shown doesn’t have anything that looks like it could be causing the problem. In general, you’re probably looking for something in an after/before save hook, or in the save process within a model. There’s not really anything in the excerpt that should be failing.

By far the most common cause of failures on the background only is a plugin using Zend_Controller_Front::getInstance()->getRequest() in a save hook or somewhere similar.

Getting the actual error logged would really help you tell what the error is (I assume it’s a PHP error that’s at fault here).

For some reason, I can’t get my installation to log errors. Either that or no errors are being thrown. In any case, I was able to fix at least part of the issue by changing…

    public function filterSearchRecordTypes($recordTypes){
	    $recordTypes['Tour'] = __('Tour');
	    return $recordTypes;		
	}

… to…

    public function filterSearchRecordTypes($recordTypes){
	    $recordTypes['TourBuilderTour'] = __('Tour');
	    return $recordTypes;		
	}

That change makes sense and allows the process to complete. It’s still not indexing Tours, but it does index Simple Pages now.

I’m a bit stumped honestly.

This is the plugin codebase, minus the search functionality (see “working” branch). I hesitate to ask anyone to look at this for me because everyone has better things to do, but… that’s what I’m basically asking anyway.

¯\_(ツ)_/¯

Your code produces the following PHP error output when indexing:

[07-Apr-2017 01:20:40 UTC] PHP Notice:  Trying to get property of non-object in /mnt/storage/htdocs/omeka/application/libraries/globals.php on line 3455
[07-Apr-2017 01:20:40 UTC] PHP Stack trace:
[07-Apr-2017 01:20:40 UTC] PHP   1. {main}() /mnt/storage/htdocs/omeka/application/scripts/background.php:0
[07-Apr-2017 01:20:40 UTC] PHP   2. Omeka_Job_Process_Wrapper->run() /mnt/storage/htdocs/omeka/application/scripts/background.php:61
[07-Apr-2017 01:20:40 UTC] PHP   3. Job_SearchTextIndex->perform() /mnt/storage/htdocs/omeka/application/libraries/Omeka/Job/Process/Wrapper.php:29
[07-Apr-2017 01:20:40 UTC] PHP   4. TourTable->getSelect() /mnt/storage/htdocs/omeka/application/models/Job/SearchTextIndex.php:44
[07-Apr-2017 01:20:40 UTC] PHP   5. is_allowed() /mnt/storage/htdocs/omeka/plugins/TourBuilder/models/TourTable.php:57
[07-Apr-2017 01:20:40 UTC] PHP Fatal error:  Call to a member function isAllowed() on null in /mnt/storage/htdocs/omeka/application/libraries/globals.php on line 3463
[07-Apr-2017 01:20:40 UTC] PHP Stack trace:
[07-Apr-2017 01:20:40 UTC] PHP   1. {main}() /mnt/storage/htdocs/omeka/application/scripts/background.php:0
[07-Apr-2017 01:20:40 UTC] PHP   2. Omeka_Job_Process_Wrapper->run() /mnt/storage/htdocs/omeka/application/scripts/background.php:61
[07-Apr-2017 01:20:40 UTC] PHP   3. Job_SearchTextIndex->perform() /mnt/storage/htdocs/omeka/application/libraries/Omeka/Job/Process/Wrapper.php:29
[07-Apr-2017 01:20:40 UTC] PHP   4. TourTable->getSelect() /mnt/storage/htdocs/omeka/application/models/Job/SearchTextIndex.php:44
[07-Apr-2017 01:20:40 UTC] PHP   5. is_allowed() /mnt/storage/htdocs/omeka/plugins/TourBuilder/models/TourTable.php:57

This is somewhatmostly Omeka’s fault: is_allowed doesn’t work when the ACL isn’t loaded. (Plus there’s another problem with getting the “bootstrap” object but that’s somewhat beside the point).

If you look at other stuff that uses is_allowed in these kinds of places, they first check if the ACL exists before trying to check if something’s allowed. We can handle this situation more gracefully, but it’s a pretty simple workaround in the plugin, in models/TourTable.php’s getSelect(), alter the is_allowed check like this:

$acl = Zend_Registry::get('bootstrap')->getResource('Acl');
if( $acl &&  ! is_allowed( 'TourBuilder_Tours', 'show-unpublished' ) )

Additionally, the change you made that “fixed” the job is wrong. That key in the search record types array needs to be the name of your record. In your case, that’s “Tour”, not “TourBuilderTour.” It only seemed to fix things because it totally broke search indexing for your plugin, so the problematic code in the TourTable never got run.

Thanks so much @jflatnes, this is super helpful. I’ll work on getting my error logging working now.

You can also try the code without the workaround out on the current master branch version of Omeka: it should fix the fatal error you’re seeing here.