OJS OCS OMP OHS

You are viewing the PKP Support Forum | PKP Home Wiki



Callback every time a submission file is uploaded

OJS development discussion, enhancement requests, third-party patches and plug-ins.

Moderators: jmacgreg, btbell, michael, bdgregg, barbarah, asmecher

Forum rules
Developer Resources:

Documentation: The OJS Technical Reference and the OJS API Reference are both available from the OJS Documentation page.

Git: You can access our public Git Repository here. Comprehensive Git usage instructions are available on the wiki.

Bugzilla: You can access our Bugzilla report tracker here.

Search: You can use our Google Custom Search to search across our main website, the support forum, and Bugzilla.

Questions and discussion are welcome, but if you have a workflow or usability question you should probably post to the OJS Editorial Support and Discussion subforum; if you have a technical support question, try the OJS Technical Support subforum.

Callback every time a submission file is uploaded

Postby Donovan » Wed Dec 21, 2011 2:52 am

Hi,

I'm writing a plugin and I need to call a function every time a submission file is uploaded.
So far I managed to get it working by using "TemplateManager::display" and checking the .tpl that is being used.

However now I need to call this function also when the import is made through the native importexport plugin.
Is there a way to know when a submission file is being uploaded and associated to an article?

Thank you in advance.
Donovan
 
Posts: 8
Joined: Thu Jun 23, 2011 1:22 am

Re: Callback every time a submission file is uploaded

Postby mcrider » Mon Jan 02, 2012 2:18 pm

Hi Donovan,

There isn't a generic 'submission file uploaded' hook; You'll have to make sure a hook is called in all places submission files are uploaded. The Plagiarism plugin is an example of registering against the submission file upload in the 5-step submission process -- for all other places where files are uploaded (i.e. the import export plugin), you'll have to register against the hook in there (or create one if it doesn't exist).

Cheers,
Matt
mcrider
 
Posts: 952
Joined: Mon May 05, 2008 10:29 am
Location: Vancouver, BC

Re: Callback every time a submission file is uploaded

Postby Donovan » Wed Jan 04, 2012 2:41 am

Hi Matt and thanks for your reply.
I will take a look to the plugin. :-)

Alberto
Donovan
 
Posts: 8
Joined: Thu Jun 23, 2011 1:22 am

Re: Callback every time a submission file is uploaded

Postby Damion » Tue Mar 19, 2013 2:26 pm

I am doing some new work on an OJS module to process uploaded articles (wherever they are uploaded) into pdf, xml and html formats. In trying to get my first file upload hook to work, i am logged into an OJS test site as an editor and am looking at the Editing page for an article, e.g.

http://ubie/ojs/index.php/chaos/editor/ ... nEditing/1

I can see that on this page the "editor" role actions on this page are handled by the /classes/submission/sectionEditor/SectionEditorAction.inc.php classes. I'm playing with the HookRegistry SectionEditorAction::uploadCopyeditVersion call to trigger my own plugin to do a process on the uploaded file. I can see the uploadCopyeditVersion() function is firing when I hit the Upload button in the CopyEditor section, but it doesn't seem to be making it to my callback function. I set up the callback in the plugin pretty simply as:

HookRegistry::register('SectionEditorAction::uploadCopyeditVersion', array(&$this, 'fileCallback'));

But a die("made it this far") planted in my fileCallback() function isn't firing, nor a log command there; it seems like its getting ignored.

So my question is, is there anything special one must do to get the HookRegistry to reset itself visa vis knowing the needs of each plugin? Is a plugin Disable / Enable cycle enough for the HookRegistry to get new info or do I have to be more extreme and delete/reinstall my plugin (during the testing cycle)?

Thanks,
Last edited by Damion on Tue Mar 19, 2013 3:10 pm, edited 1 time in total.
Damion
 
Posts: 14
Joined: Tue Mar 19, 2013 12:09 pm

Re: Callback every time a submission file is uploaded

Postby asmecher » Tue Mar 19, 2013 2:43 pm

Hi Damion,

Plugins need to be registered in the database before you'll get hook callbacks; the tools/upgrade.php script can do this if you use it to run through the upgrade process, or alternately you can look at the existing plugin entries as templates.

Regards,
Alec Smecher
Public Knowledge Project Team
asmecher
 
Posts: 8470
Joined: Wed Aug 10, 2005 12:56 pm

Re: Callback every time a submission file is uploaded

Postby Damion » Tue Mar 19, 2013 3:12 pm

Righto, thanks Alec. I just figured this out from thread viewtopic.php?f=9&t=7386 , one must insert a "versions" table record for one's plugin; I did this via an insert statement

INSERT INTO versions (major, minor, revision, build, date_installed,current,product_type,product,product_class_name)
SELECT 1,0,0,0, now(),1,'plugins.generic','exampleappname','ExampleClassName'

Including this here as it is useful for making a new plugin that isn't ready for install via tar.gz file.
Damion
 
Posts: 14
Joined: Tue Mar 19, 2013 12:09 pm

Re: Callback every time a submission file is uploaded

Postby Damion » Fri Mar 22, 2013 11:26 pm

One question. I'm trying to create and upload a supplemental file in response to user's uploaded article file. I need to create an article_supplemental_file record. I have a known good $fileId, good $articleId.

I'm trying to set up the insertSuppFile() call with minimal fields:

$fileId = $articleFileManager -> copySuppFile($archiveURL, "application/zip");

import('classes.article.SuppFile');
$suppFile = new SuppFile(); //See classes/article/SuppFile.inc.php
$suppFile->setArticleId($articleId);
$suppFile->setFileId($fileId);

$suppFile->setTitle('Converted Documents', null); // Localized
$suppFile->setType(''); //possibly 'common.other'
$suppFile->setTypeOther("ZIP Archive", null); // $this->getData('typeOther') Localized
$suppFile->setDescription("Could be a manifest here", null); // Localized
$suppFile->setDateCreated( Core::getCurrentDate() );
$suppFile->setShowReviewers(0);

$suppFileDao->insertSuppFile($suppFile);

But although the new supplimental record is created this way, and file is associated with it, the setTypeOther isn't set, nor is the title (not in db). I see that the localizable text fields are handled by $this->updateLocaleFields($suppFile); in SuppFileDAO.inc.php . Is there something more I need to do...?
...
Damion
 
Posts: 14
Joined: Tue Mar 19, 2013 12:09 pm

Re: Callback every time a submission file is uploaded

Postby asmecher » Sat Mar 23, 2013 8:01 am

Hi Damion,

Localized fields need to be set by locale, e.g.:
Code: Select all
$suppFile->setTitle('This is my English title', 'en_US');
...OR...
Code: Select all
$suppFile->setTitle(array('en_US' => 'My English title', 'es_ES' => 'Lo mismo en Espanol'));
Regards,
Alec Smecher
Public Knowledge Project Team
asmecher
 
Posts: 8470
Joined: Wed Aug 10, 2005 12:56 pm

Re: Callback every time a submission file is uploaded

Postby Damion » Mon Mar 25, 2013 2:44 pm

ok, thanks! (I had taken a wild guess that "null" would just lead to a default title being used.)
Damion
 
Posts: 14
Joined: Tue Mar 19, 2013 12:09 pm

Re: Callback every time a submission file is uploaded

Postby Damion » Wed Apr 24, 2013 6:41 pm

The next challenge in this plugin project is about how to spawn a php thread that will perform lengthy tasks on the uploaded file. Since all the heavy work is to be done by this separate thread, the user will be able to resume other operations immediately after his/her file upload.

Should I stay clear of a pcntl_fork() approach? Is there a recommended way to do this in OJS?

The forked call takes a few basic parameters:

function _submitDocument($articleId, $journalId, $articleFilePath) { ... }

so it could run in a php command line version like "submitDocument.php [param 1] [param 2] [param 3]

But of course the issue is that submitDocument.php needs access to a few OJS Classes:
$articleDao = &DAORegistry::getDAO('ArticleDAO');
$article = &$articleDao->getArticle($articleId);
and later
import('classes.file.ArticleFileManager');
$articleFileManager = new ArticleFileManager($articleId);
etc.

I guess one approach is to make a wget web call using the user's browser credentials to the ojs site with the action coded in the url parameters. But is there a way to just launch a separate thread server side which has easy access to the same class/method calls as the plugin code itself?

Advice appreciated!
Damion
 
Posts: 14
Joined: Tue Mar 19, 2013 12:09 pm

Re: Callback every time a submission file is uploaded

Postby asmecher » Wed Apr 24, 2013 11:19 pm

Hi Damion,

Have a look at the ProcessDAO and related classes; they're used by the citation assistant to launch longer-running back end tasks without tying up the user. It's a weird work-around but PHP doesn't offer many facilities for doing this in better ways...

Regards,
Alec Smecher
Public Knowledge Project Team
asmecher
 
Posts: 8470
Joined: Wed Aug 10, 2005 12:56 pm

Re: Callback every time a submission file is uploaded

Postby Damion » Thu Apr 25, 2013 10:02 pm

Findings on ProcessDAO:
- allows one to set up a request for an operation e.g. "getDocumentMarkup".
- allows one to trigger a pre-set number of parallel calls to this operation, e.g. 4
- an operation's call has a pre-set amount of time to execute, after that it is marked as a "zombie".
- expectation is that as each individual operation call is finished it gets removed from the list/count, thus making more room for subsequent requests for an operation.
- no parameters can be passed through to the operation handler so extra information has to be communicated indirectly, e.g. by having handler go look at a queue.

Seems like this is oriented towards system-wide database table driven operations. If we set up a queue of tasks, then we could trigger spawnProcesses() , and each process thread could be dedicated to the next available queue item. Subsequent calls to spawnProcesses() just ensure that the full compliment of threads are working on the given task?

Rather than get into the queue thing, is it possible to utilize something like the CliTool ? Looking at triggering getDocumentMarkup with parameters very much like tools/mergeUsers.php ?
Damion
 
Posts: 14
Joined: Tue Mar 19, 2013 12:09 pm

Re: Callback every time a submission file is uploaded

Postby asmecher » Fri Apr 26, 2013 9:32 am

Hi Damion,

The CliTool-based tools are intended for manual invocation from the command line, so I'm not sure they'll help you much with operational tasks; you could also look at the ScheduledTask class (and related classes), which are intended to be run periodically (i.e. daily) by cron. However, many users don't have the ability to set up cron tasks (e.g. on shared hosts) so it'll cut down considerably on the number of users who are able to run it.

Regards,
Alec Smecher
Public Knowledge Project Team
asmecher
 
Posts: 8470
Joined: Wed Aug 10, 2005 12:56 pm

Re: Callback every time a submission file is uploaded

Postby Damion » Fri Apr 26, 2013 11:52 am

The document markup task needs to be run as quickly as possible, so I did try the command line invocation rather than a scheduled approach. I was able to set it up so that the various hooks for uploading a file would catch its temporary location, then send to

exec("/usr/bin/php ./DocumentMarkupCliTool.php $articleId $journalId $articleFilePath > /dev/null 2>/dev/null &");

with the DocumentMarkupCliTool.php script looking alot like mergeUsers.php, bringing in only the classes/environment required to do the task at hand. So that seems to be working well with the long task running until complete in the background. I guess the issue now is to make sure DocumentMarkupCliTool.php always exits and never hangs. Any other concerns about using exec this way? $articleFilePath is vetted as a straight path to temporary copy of uploaded file.

A nice side effect of this is that the details of the script's work are reported when testing directly from the commmand line. I was able to catch a few bugs that way.
Damion
 
Posts: 14
Joined: Tue Mar 19, 2013 12:09 pm

Re: Callback every time a submission file is uploaded

Postby asmecher » Fri Apr 26, 2013 12:32 pm

Hi Damion,

There are several downsides to that approach -- you'll need to know where the PHP binary is, for example, and it's fairly *NIX-centric. It's basically equivalent to using pcntl_fork but more convoluted; if you go that route, better just to use pcntl_fork directly.

I think the reason the ProcessDAO structures were written is to accomplish the same thing but not leave it dependent on the original user's request. The ProcessDAO etc. are used to solve a similar problem to the one you're encountering: when submitting an article with a long list of citations, how do we check/parse/correlate all those citations against external services without delaying the user?

Regards,
Alec Smecher
Public Knowledge Project Team
asmecher
 
Posts: 8470
Joined: Wed Aug 10, 2005 12:56 pm

Next

Return to OJS Development

Who is online

Users browsing this forum: Google [Bot], Yahoo [Bot] and 1 guest