Work with files

Hello everyone,

I have an idea with marking files in submission. I want to get the location of file - of every article in issue and show them on my own page. Could you help me with some start, what functions I should use? Or which handler is right for my stuff?

I found functions getFile() and readFile() in ArticleFileManager.inc.php. Is this right way how to work with physical fe. PDF files?

Thanks a lot.

Duff

Hi @duff,

Could you describe a little more specifically what youā€™re trying to do? Are you hoping to turn the publication front-end into a megajournal, for example, or something different?

Regards,
Alec Smecher
Public Knowledge Project Team

Hi asmecher,

Sorry for brevity in my first question. I need to make my own operations upon the article file (I have some script, which edit PDF document, and I need to edit every article in issue - not important now, only for imagine). So i need to get a full path to file of article. Is that better explanation?

Thank you.

duff

Hi @duff,

This will depend on what youā€™re doing a little more specifically. But if you want to walk through all the files in your journal, then youā€™re probably best using a mixture of different DAOs. For example (untested but should serve)ā€¦

$articleDao =& DAORegistry::getDAO();
$articleFileDao =& DAORegistry::getDAO('ArticleFileDAO');
import('classes.file.ArticleFileManager');

$articles = $articleDao->getArticlesByJournalId($journalId);
while ($article =& $articles->next()) {
    $articleFileManager = new ArticleFileManager($articleId);
    $articleFiles =& $articleFileDao->getArticleFilesByArticle($article->getId());
    foreach ($articleFiles as $articleFile) {
        ...do something here...
    }
    unset($article);
}

Have a look at ArticleFileManager to see whatā€™s available for functions there; it doesnā€™t currently expose the full path outside that class, I donā€™t think, so you may have to assemble the pathname yourself.

Regards,
Alec Smecher
Public Knowledge Project Team

Hi @asmecher,

for start thanks a lot, i donā€™t need all articles of journal, but only of current issue. But itā€™s ok. I think, when I need files of current issue, i will use IssueFileDAO, right?

Iā€™ve tried your code, but I get and ā€œUnrecognized DAO !ā€, Iā€™ve browsed Application.inc.php, and it seems ok - getDAO('ArticleFileDAO'). So I updated your code $articleDao =& DAORegistry::getDAO(); -->added
$articleDao =& DAORegistry::getDAO(ā€˜ArticleDAOā€™);

Just first step Iā€™m trying:

import('classes.article.ArticleFileDAO');        
    $articleDao =& DAORegistry::getDAO('ArticleDAO');
    $articleFileDao =& DAORegistry::getDAO('ArticleFileDAO');
    import('classes.file.ArticleFileManager');
    $articles = $articleDao->getArticlesByJournalId($journalId);
    while ($article =& $articles->next()) {
    $articleFileManager = new ArticleFileManager($articleId);
    $articleFiles =& $articleFileDao->getArticleFilesByArticle($article->getId());
    foreach ($articleFiles as $articleFile) {
        echo $articleFile;
    }
    unset($article);

with an error:

Fatal error: Call to a member function getJournalId() on a non-object in C:\xampp\htdocs\ojs245\classes\file\ArticleFileManager.inc.php on line 52

It should output a list of files of journal, is that right?

duff

Hi,

Iā€™ve added

$journalId = (int) $journalId;

But now, Iā€™m getting blank page. So, is there any more to write, just to test this code?

Thanks a lot.

duff

Hi @duff,

I think the $articleId variable isnā€™t initialized. Use $article->getId() instead of $articleId.

Regards,
Alec Smecher
Public Knowledge Project Team

Hi @asmecher,

we wrote in same time :). Iā€™ve added

$journalId = (int) $journalId;

But now, only blank page, without informations. When I tried to use $article->getId(); - no changes. Still blank page.

duff

Hi @duff,

Can you put your changes online as a fork to the OJS repository on github.com? Itā€™s much easier to spot and comment on issues there.

Regards,
Alec Smecher
Public Knowledge Project Team

Hi @asmecher,

For now, itā€™s my own page, and I have only this code in StampHadler:

import('classes.handler.Handler');
class StampHandler extends Handler {
    function stampingOperation($args, $request) {
         
        $templateMgr = TemplateManager::getManager($request);
        $templateMgr->display('stamp/stampingOperation.tpl');

        $articleDao =& DAORegistry::getDAO('ArticleDAO');
        $articleFileDao =& DAORegistry::getDAO('ArticleFileDAO');
        import('classes.file.ArticleFileManager');
        
        $journalId = (int) $journalId;                                                           
        
        
        
        $articles = $articleDao->getArticlesByJournalId($journalId);
        while ($article =& $articles->next()) {
        $articleFileManager = new ArticleFileManager($article->getId());
        $articleFiles =& $articleFileDao->getArticleFilesByArticle($article->getId());
        foreach ($articleFiles as $articleFile) {
            echo 'FILE';
        }
        unset($article);
        }

    }

} 

So, i donā€™t want to upload it.But if I can upload there my own page, I will do it :).

Thanks,

duff

edit:
I forked it and commited my ownpage:

Hi,

iā€™ve resolved the listing of journal articles:
import(ā€˜classes.handler.Handlerā€™);

class StampHandler extends Handler {

    function stampingOperation($args, $request) {
      $templateMgr = TemplateManager::getManager($request);
      $templateMgr->display('stamp/stampingOperation.tpl');

      $articleDao =& DAORegistry::getDAO('ArticleDAO');
      $articleFileDao =& DAORegistry::getDAO('ArticleFileDAO');
      import('classes.file.ArticleFileManager');
      
      $articles = $articleDao->getArticlesByJournalId($journalId);
      while ($article =& $articles->next()) {
        $articleFileManager = new ArticleFileManager($article->getId());
        $articleFiles =& $articleFileDao->getArticleFilesByArticle($article->getId());
        foreach ($articleFiles as $articleFile) {
            
            $filePath = $articleFileManager->filesDir .  $articleFileManager->fileStageToPath($articleFile->getFileStage()) . '/' . $articleFile->getFileName();    
            echo $filePath.'<br>';
        unset($article);
        }
      }
    }
}

So this is ok - the output is the filename of every article in my journal. Iā€™ve got every information, what I need. The second task of my plan is to list articles only of current Issue, but i didnā€™t found similar function as getArticlesByJournal(). Is there any predefined function, which I could use?

Second Question about enablePageNumber - how can I turn on this function to show pages of Article on IssueToc? Is that part of any plugin?

Thanks a lot.

duff

Hi @duff,

Have a look at the getCurrentIssue function of IssueDAO.
http://pkp.sfu.ca/ojs/doxygen/stable/html/classIssueDAO.html

Regards,
Alec Smecher
Public Knowledge Project Team

Hi @asmecher,

Iā€™d looked on this before, but i donā€™t think, that is what I need. I need to select only for example articles from issue 2. The parameter of getCurrentIssue() is $journalId, so i have no idea, how use it to filter these articles.

I will place my script on IssueToc page, where is the list of articles, and I need their physical files. Could you please describe me more your suggestion? Thank you.

duff

Hi @duff,

There are lots of good examples in the Technical Reference and the existing codebase; Iā€™d suggest doing some exploring there. Iā€™m happy to help here, but a little wary of the time cost in guiding through coding specifics ā€“ the development team is the same as the support team here. Do some reading, and if you really get stuck, I can perhaps identify some useful examples.

Regards,
Alec Smecher
Public Knowledge Project Team

Hi @asmecher,

Iā€™m sorry, of course I understand this. Iā€™m preparing my own function to retrieve articles, which I need. Iā€™m using TR, so I hope, i will be succesful. Thanks a lot for your help.

duff

Hi @duff,

Sure ā€“ and if/when you do get stuck, Iā€™ll be happy to help over here.

Regards,
Alec Smecher
Public Knowledge Project Team

Hello @asmecher,

Iā€™ve solved out almost everything what I need and make a big step, but now, Iā€™m trying to get last thing, which I need in my script. Itā€™s the Author Name (First and Last) of Article.

I was trying to find some function, but Iā€™ve found only getLastName(), which isnā€™t exactly what I need. Itā€™s an array, an I have no idea, how to get the right information what I need (because of that object in array).

So, before I start to make my own way, how to get Author full name, could you please help me with some ā€œkickā€ if there is some easy way how to get Author name, if Iā€™m getting articles and files, with script above.

I tried one thing:

function &getAuthorByArticleId($articleId = null) {
		$primaryLocale = AppLocale::getPrimaryLocale();
		$locale = AppLocale::getLocale();
    
		if ($articleId !== null) $params[] = (int) $articleId;
    
		$result =& $this->retrieve('SELECT	aut.* FROM	authors aut WHERE aut.submission_id ='.$articleId);
    
		$returner = new DAOResultFactory($result, $this, '_returnArticleFromRow');
		return $returner;
	}

And then, in IssueManagementHandler.inc.php Iā€™m doing this in foreach:

 $articleAuthor = $articleDao->getAuthorByArticleId($article->getId());
    
    $TempAuthor = $articleAuthor;

but $TempAuthor is null. Thank for some help.

Best regards,

duff

Hi @duff,

It shouldnā€™t be necessary to write your own function for this. Depending on what kind of answer you want to get from the database, there are two things you can do:

  • For the submitting user (who may or may not be the author, but generally is), use $article->getUserId(), e.gā€¦

      $userDao =& DAORegistry::getDAO('UserDAO');
      $submittingUser =& $userDao->getById($article->getUserId();
    

    You can then work with the $submittingUser variable, which will be a User object.

  • For the authors themselves, use $article->getAuthors(). For exampleā€¦

      $authors =& $article-.getAuthors();
      foreach ($authors as $author) {
          (work with the $author object)
      }
    

    These will be Author objects.

Regards,
Alec Smecher
Public Knowledge Project Team

Thank you asmecher, the second thing is what I need. Still have to learn.

If I could please you about one last thing. On the IssueToc I have as input in foreach the files of every article which is scheduled to this issue.

In basis, the order of the articles is sorted by the filename - e.g.
28-88-1-PB.pdf
29-89-1-PB.pdf
30-90-1-PB.pdf
ā€¦

Iā€™ve scored one case, where I upload testing documents ā€œrightā€ way, first article1.pdf, second article2.pdf, third article3.pdf, etcā€¦ But the order was changed like this: article3.pdf, article1.pdf, article2.pdf - thatā€™s only an example. I donā€™t know, why itā€™s happened, in other issues, that was ok.

But, main thing - In issueToc, there are possiblity to moveArticles and change order before publishing. Iā€™m using modificated script (4th reply) to get files of these articles - but it doesnā€™t respect changed order. Thatā€™s clear.

If I would like to get articles in right order, I need to use same function like in issueToc:

// get issue sections and articles
		$publishedArticleDao =& DAORegistry::getDAO('PublishedArticleDAO');
		$publishedArticles = $publishedArticleDao->getPublishedArticles($issueId);

		$layoutEditorSubmissionDao =& DAORegistry::getDAO('LayoutEditorSubmissionDAO');
		$proofedArticleIds = $layoutEditorSubmissionDao->getProofedArticlesByIssueId($issueId);
		$templateMgr->assign('proofedArticleIds', $proofedArticleIds);

		$currSection = 0;
		$counter = 0;
		$sections = array();
		$sectionCount = 0;
		$sectionDao =& DAORegistry::getDAO('SectionDAO');
		foreach ($publishedArticles as $article) {
			$sectionId = $article->getSectionId();
			if ($currSection != $sectionId) {
				$lastSectionId = $currSection;
				$sectionCount++;
				if ($lastSectionId !== 0) $sections[$lastSectionId][5] = $customSectionOrderingExists?$sectionDao->getCustomSectionOrder($issueId, $sectionId):$sectionCount; // Store next custom order
				$currSection = $sectionId;
				$counter++;
				$sections[$sectionId] = array(
					$sectionId,
					$article->getSectionTitle(),
					array($article),
					$counter,
					$customSectionOrderingExists?
						$sectionDao->getCustomSectionOrder($issueId, $lastSectionId): // Last section custom ordering
						($sectionCount-1),
					null // Later populated with next section ordering
				);

I didnā€™t understand this script very well. Is there possible to fill the array $articleFiles in above script with sorted articles like in this case? If editor make changes in order, than save it. Iā€™m sorry about my question, but this is too difficult for me still.

Thanks a lot.

duff

Hi @duff,

If you want to get the articles for an issue in the order of publication, youā€™ll need to use the PublishedArticleDAO. The getPublishedArticles and getPublishedArticlesInSections functions, for example, use the ordering youā€™re looking for.

Regards,
Alec Smecher
Public Knowledge Project Team