Open Journal Systems  3.3.0
TextureHandler.inc.php
1 <?php
2 
16 import('classes.handler.Handler');
17 
18 class TextureHandler extends Handler {
20  protected $_plugin;
21 
25  function __construct() {
26 
27  parent::__construct();
28 
29  $this->_plugin = PluginRegistry::getPlugin('generic', TEXTURE_PLUGIN_NAME);
30  $this->addRoleAssignment(
31  array(ROLE_ID_MANAGER, ROLE_ID_SUB_EDITOR, ROLE_ID_ASSISTANT, ROLE_ID_REVIEWER, ROLE_ID_AUTHOR),
32  array('editor', 'json', 'media', 'createGalleyForm', 'createGalley')
33  );
34  }
35 
39  function authorize($request, &$args, $roleAssignments) {
40  import('lib.pkp.classes.security.authorization.SubmissionFileAccessPolicy');
41  $this->addPolicy(new SubmissionFileAccessPolicy($request, $args, $roleAssignments, SUBMISSION_FILE_ACCESS_READ));
42  return parent::authorize($request, $args, $roleAssignments);
43  }
44 
45 
52  public function createGalleyForm($args, $request) {
53 
54  import('plugins.generic.texture.controllers.grid.form.TextureArticleGalleyForm');
55  $galleyForm = new TextureArticleGalleyForm(
56  $request,
57  $this->getPlugin(),
58  $this->getSubmission()
59  );
60 
61  $galleyForm->initData();
62  return new JSONMessage(true, $galleyForm->fetch($request));
63  }
64 
70  public function createGalley($args, $request) {
71 
72  import('plugins.generic.texture.controllers.grid.form.TextureArticleGalleyForm');
73 
74  $galleyForm = new TextureArticleGalleyForm($request, $this->getPlugin(), $this->getSubmission());
75  $galleyForm->readInputData();
76 
77  if ($galleyForm->validate()) {
78 
79  $galleyForm->execute();
80 
81  return $request->redirectUrlJson($request->getDispatcher()->url($request, ROUTE_PAGE, null, 'workflow', 'access', null,
82  array(
83  'submissionId' => $request->getUserVar('submissionId'),
84  'stageId' => $request->getUserVar('stageId')
85  )
86  ));
87 
88  }
89 
90  return new JSONMessage(false);
91  }
92 
100  public function editor($args, $request) {
101  $stageId = (int)$request->getUserVar('stageId');
102  $fileId = (int)$request->getUserVar('fileId');
103  $submissionId = (int)$request->getUserVar('submissionId');;
104  if (!$submissionId || !$stageId || !$fileId) {
105  fatalError('Invalid request');
106  }
107 
108  $editorTemplateFile = method_exists($this->_plugin, 'getTemplateResource') ? $this->_plugin->getTemplateResource('editor.tpl') : ($this->_plugin->getTemplateResourceName() . ':templates/editor.tpl');
109  $router = $request->getRouter();
110  $documentUrl = $router->url($request, null, 'texture', 'json', null,
111  array(
112  'submissionId' => $submissionId,
113  'fileId' => $fileId,
114  'stageId' => $stageId,
115  )
116  );
117 
118  PKPLocale::requireComponents(LOCALE_COMPONENT_APP_COMMON, LOCALE_COMPONENT_PKP_MANAGER);
119  $templateMgr = TemplateManager::getManager($request);
120  $templateMgr->assign(array(
121  'documentUrl' => $documentUrl,
122  'textureUrl' => $this->_plugin->getTextureUrl($request),
123  'texturePluginUrl' => $this->_plugin->getPluginUrl($request),
124  ));
125  return $templateMgr->fetch($editorTemplateFile);
126  }
127 
128 
137  public function json($args, $request) {
138 
139  $submissionFile = $this->getAuthorizedContextObject(ASSOC_TYPE_SUBMISSION_FILE);
140 
141  if (!$submissionFile) {
142  fatalError('Invalid request');
143  }
144 
145  if (empty($submissionFile)) {
146  echo __('plugins.generic.texture.archive.noArticle'); // TODO custom message
147  exit;
148  }
149 
150  if ($_SERVER["REQUEST_METHOD"] === "DELETE") {
151  $postData = file_get_contents('php://input');
152  $media = (array)json_decode($postData);
153  if (!empty($media)) {
154  $submissionFileDao = DAORegistry::getDAO('SubmissionFileDAO');
155  $dependentFiles = $submissionFileDao->getLatestRevisionsByAssocId(
156  ASSOC_TYPE_SUBMISSION_FILE,
157  $submissionFile->getFileId(),
158  $submissionFile->getSubmissionId(),
159  SUBMISSION_FILE_DEPENDENT
160  );
161  foreach ($dependentFiles as $dependentFile) {
162  if ($dependentFile->getOriginalFileName() === $media['fileName']) {
163  $fileId = $dependentFile->getFileId();
164  $submissionId = (int)$request->getUserVar('submissionId');
165  $fileStage = $dependentFile->getFileStage();
166  $fileRevision = $submissionFileDao->deleteLatestRevisionById($fileId, $fileStage, $submissionId);
167  if ($fileRevision > 0) {
168  return new JSONMessage(true, array(
169  'submissionId' => $submissionId,
170  'fileId' => $submissionId,
171  'fileRevision' => $fileRevision,
172  'delete_stauts' => true
173  ));
174  } else {
175  return new JSONMessage(false);
176  }
177  break;
178  }
179  }
180  }
181  }
182 
183  if ($_SERVER["REQUEST_METHOD"] === "GET") {
184  $assets = array();
185  $filePath = $submissionFile->getFilePath();
186  $manuscriptXml = file_get_contents($filePath);
187  $manifestXml = $this->_buildManifestXMLFromDocument($manuscriptXml, $assets);
188  $manuscriptXmlDom = $this->_removeElements($manuscriptXml);
189  $mediaInfos = $this->_buildMediaInfo($request, $assets);
190  $resources = array(
191  'manifest.xml' => array(
192  'encoding' => 'utf8',
193  'data' => $manifestXml,
194  'size' => strlen($manifestXml),
195  'createdAt' => 0,
196  'updatedAt' => 0,
197  ),
198  'manuscript.xml' => array(
199  'encoding' => 'utf8',
200  'data' => $manuscriptXmlDom->saveXML(),
201  'size' => filesize($filePath),
202  'createdAt' => 0,
203  'updatedAt' => 0,
204  ),
205  );
206  $mediaBlob = array(
207  'version' => $submissionFile->getSourceRevision(),
208  'resources' => array_merge($resources, $mediaInfos)
209  );
210  header('Content-Type: application/json');
211  return json_encode($mediaBlob, JSON_UNESCAPED_SLASHES);
212  } elseif ($_SERVER["REQUEST_METHOD"] === "PUT") {
213 
214  $postData = file_get_contents('php://input');
215 
216  if (!empty($postData)) {
217  $submissionDao = DAORegistry::getDAO('SubmissionDAO'); /* @var $submissionDao SubmissionDAO */
218  $submissionId = (int)$request->getUserVar('submissionId');
219  $submission = $submissionDao->getById($submissionId);
220 
221  $resources = (array)json_decode($postData)->archive->resources;
222  $media = (array)json_decode($postData)->media;
223 
224  if (!empty($media)) {
225  import('classes.file.PublicFileManager');
226  $publicFileManager = new PublicFileManager();
227 
228 
229  $journal = $request->getJournal();
230  $genreDao = DAORegistry::getDAO('GenreDAO');
231  $genres = $genreDao->getByDependenceAndContextId(true, $journal->getId());
232  $genreId = null;
233  $extension = $publicFileManager->getImageExtension($media["fileType"]);
234  while ($candidateGenre = $genres->next()) {
235  if ($extension) {
236  if ($candidateGenre->getKey() == 'IMAGE') {
237  $genreId = $candidateGenre->getId();
238  break;
239  }
240  } else {
241  if ($candidateGenre->getKey() == 'MULTIMEDIA') {
242  $genreId = $candidateGenre->getId();
243  break;
244 
245  }
246  }
247  }
248  if (!$genreId) {
249  // Could not identify the genre -- it's an error condition
250  return new JSONMessage(false);
251  }
252 
253  $user = $request->getUser();
254  $insertedSubmissionFile = $this->_createDependentFile($genreId, $media, $submission, $submissionFile, $user);
255 
256 
257  } elseif (!empty($resources) && isset($resources['manuscript.xml']) && is_object($resources['manuscript.xml'])) {
258  $genreId = $submissionFile->getGenreId();
259  $fileStage = $submissionFile->getFileStage();
260  $user = $request->getUser();
261 
262  $insertedSubmissionFile = $this->_updateManuscriptFile($fileStage, $genreId, $resources, $submission, $submissionFile, $user);
263 
264  } else {
265  return new JSONMessage(false);
266  }
267 
268  return new JSONMessage(true, array(
269  'submissionId' => $insertedSubmissionFile->getSubmissionId(),
270  'fileId' => $insertedSubmissionFile->getFileIdAndRevision(),
271  'fileStage' => $insertedSubmissionFile->getFileStage(),
272  ));
273 
274  }
275 
276  } else {
277  return new JSONMessage(false);
278  }
279  }
280 
281 
289  protected function _buildMediaInfo($request, $assets) {
290  $infos = array();
291  $mediaDir = 'texture/media';
292  $context = $request->getContext();
293  $router = $request->getRouter();
294  $dispatcher = $router->getDispatcher();
295  $fileId = $request->getUserVar('fileId');
296  $stageId = $request->getUserVar('stageId');
297  $submissionId = $request->getUserVar('submissionId');
298  // build mapping to assets file paths
299  $assetsFilePaths = array();
300  $submissionFileDao = DAORegistry::getDAO('SubmissionFileDAO');
301  import('lib.pkp.classes.submission.SubmissionFile'); // Constants
302  $dependentFiles = $submissionFileDao->getLatestRevisionsByAssocId(
303  ASSOC_TYPE_SUBMISSION_FILE,
304  $fileId,
305  $submissionId,
306  SUBMISSION_FILE_DEPENDENT
307  );
308  foreach ($dependentFiles as $dFile) {
309  $assetsFilePaths[$dFile->getOriginalFileName()] = $dFile->getFilePath();
310  }
311  foreach ($assets as $asset) {
312  $path = str_replace('media/', '', $asset['path']);
313  $filePath = $assetsFilePaths[$path];
314  $url = $dispatcher->url($request, ROUTE_PAGE, null, 'texture', 'media', null, array(
315  'submissionId' => $submissionId,
316  'fileId' => $fileId,
317  'stageId' => $stageId,
318  'fileName' => $path,
319  ));
320  $infos[$asset['path']] = array(
321  'encoding' => 'url',
322  'data' => $url,
323  'size' => filesize($filePath),
324  'createdAt' => filemtime($filePath),
325  'updatedAt' => filectime($filePath),
326  );
327  }
328  return $infos;
329  }
330 
337  protected function _buildManifestXMLFromDocument($manuscriptXml, &$assets) {
338  $dom = new DOMDocument();
339  if (!$dom->loadXML($manuscriptXml)) {
340  fatalError("Unable to load XML document content in DOM in order to generate manifest XML.");
341  }
342 
343  $k = 0;
344  $assets = array();
345  $figElements = $dom->getElementsByTagName('fig');
346  foreach ($figElements as $figure) {
347  $pos = $k + 1;
348  $figItem = $figElements->item($k);
349  $graphic = $figItem->getElementsByTagName('graphic');
350  if (sizeof($graphic) > 0) {
351 
352  // figure without graphic?
353  if (!$figItem || !$graphic) {
354  continue;
355  }
356 
357  // get fig id
358  $figId = null;
359  if ($figItem->hasAttribute('id')) {
360  $figId = $figItem->getAttribute('id');
361  } else {
362  $figId = "ojs-fig-{$pos}";
363  }
364 
365  // get path
366  $figGraphPath = $graphic->item(0)->getAttribute('xlink:href');
367 
368  // save assets
369  $assets[] = array(
370  'id' => $figId,
371  'type' => 'image/jpg',
372  'path' => $figGraphPath,
373  );
374  }
375  $k++;
376  }
377 
378  $sxml = simplexml_load_string('<dar><documents><document id="manuscript" type="article" path="manuscript.xml" /></documents><assets></assets></dar>');
379  foreach ($assets as $asset) {
380  $assetNode = $sxml->assets->addChild('asset');
381  $assetNode->addAttribute('id', $asset['id']);
382  $assetNode->addAttribute('type', $asset['type']);
383  $assetNode->addAttribute('path', $asset['path']);
384  }
385 
386  return $sxml->asXML();
387  }
388 
397  public function media($args, $request) {
398  $user = $request->getUser();
399  $context = $request->getContext();
400  $submissionFile = $this->getAuthorizedContextObject(ASSOC_TYPE_SUBMISSION_FILE);
401  if (!$submissionFile) {
402  fatalError('Invalid request');
403  }
404 
405  $submissionFileDao = DAORegistry::getDAO('SubmissionFileDAO');
406  import('lib.pkp.classes.submission.SubmissionFile'); // Constants
407  $dependentFiles = $submissionFileDao->getLatestRevisionsByAssocId(
408  ASSOC_TYPE_SUBMISSION_FILE,
409  $submissionFile->getFileId(),
410  $submissionFile->getSubmissionId(),
411  SUBMISSION_FILE_DEPENDENT
412  );
413 
414  // make sure this is an xml document
415  if (!in_array($submissionFile->getFileType(), array('text/xml', 'application/xml'))) {
416  fatalError('Invalid request');
417  }
418 
419  $mediaSubmissionFile = null;
420  foreach ($dependentFiles as $dependentFile) {
421  if ($dependentFile->getOriginalFileName() == $request->getUserVar('fileName')) {
422  $mediaSubmissionFile = $dependentFile;
423  break;
424  }
425  }
426 
427  if (!$mediaSubmissionFile) {
428  $request->getDispatcher()->handle404();
429  }
430 
431  $filePath = $mediaSubmissionFile->getFilePath();
432  header('Content-Type:' . $mediaSubmissionFile->getFileType());
433  header('Content-Length: ' . $mediaSubmissionFile->getFileSize());
434  readfile($filePath);
435  }
436 
446  protected function _createDependentFile($genreId, $mediaData, $submission, $submissionFile, $user) {
447  $mediaBlob = base64_decode(preg_replace('#^data:\w+/\w+;base64,#i', '', $mediaData["data"]));
448  $tmpfname = tempnam(sys_get_temp_dir(), 'texture');
449  file_put_contents($tmpfname, $mediaBlob);
450 
451  $submissionFileDao = DAORegistry::getDAO('SubmissionFileDAO');
452  $newMediaFile = $submissionFileDao->newDataObjectByGenreId($genreId);
453  $newMediaFile->setSubmissionId($submission->getId());
454  $newMediaFile->setSubmissionLocale($submission->getLocale());
455  $newMediaFile->setGenreId($genreId);
456  $newMediaFile->setFileStage(SUBMISSION_FILE_DEPENDENT);
457  $newMediaFile->setDateUploaded(Core::getCurrentDate());
458  $newMediaFile->setDateModified(Core::getCurrentDate());
459  $newMediaFile->setUploaderUserId($user->getId());
460  $newMediaFile->setFileSize(filesize($tmpfname));
461  $newMediaFile->setFileType($mediaData["fileType"]);
462  $newMediaFile->setAssocId($submissionFile->getFileId());
463  $newMediaFile->setAssocType(ASSOC_TYPE_SUBMISSION_FILE);
464  $newMediaFile->setOriginalFileName($mediaData["fileName"]);
465  $insertedMediaFile = $submissionFileDao->insertObject($newMediaFile, $tmpfname);
466  unlink($tmpfname);
467 
468  return $insertedMediaFile;
469  }
470 
481  protected function _updateManuscriptFile($fileStage, $genreId, $resources, $submission, $submissionFile, $user) {
482  $manuscriptXml = $resources['manuscript.xml']->data;
483  $tmpfname = tempnam(sys_get_temp_dir(), 'texture');
484  file_put_contents($tmpfname, $manuscriptXml);
485 
486 
487  $fileSize = filesize($tmpfname);
488 
489  $submissionFileDao = DAORegistry::getDAO('SubmissionFileDAO');
490  $newSubmissionFile = $submissionFileDao->newDataObjectByGenreId($genreId);
491 
492  $newSubmissionFile->setSubmissionId($submission->getId());
493  $newSubmissionFile->setSubmissionLocale($submission->getLocale());
494  $newSubmissionFile->setGenreId($genreId);
495  $newSubmissionFile->setFileStage($fileStage);
496  $newSubmissionFile->setDateUploaded(Core::getCurrentDate());
497  $newSubmissionFile->setDateModified(Core::getCurrentDate());
498  $newSubmissionFile->setOriginalFileName($submissionFile->getOriginalFileName());
499  $newSubmissionFile->setUploaderUserId($user->getId());
500  $newSubmissionFile->setFileSize($fileSize);
501  $newSubmissionFile->setFileType($submissionFile->getFileType());
502  $newSubmissionFile->setSourceFileId($submissionFile->getFileId());
503  $newSubmissionFile->setSourceRevision($submissionFile->getRevision());
504  $newSubmissionFile->setFileId($submissionFile->getFileId());
505  $newSubmissionFile->setRevision($submissionFile->getRevision() + 1);
506  $insertedSubmissionFile = $submissionFileDao->insertObject($newSubmissionFile, $tmpfname);
507 
508  unlink($tmpfname);
509 
510  return $insertedSubmissionFile;
511  }
512 
517  private function _removeElements($manuscriptXml) {
518  $elementsPath = array("/article/front/journal-meta", "/article/front/article-meta/self-uri");
519 
520  $manuscriptXmlDom = new DOMDocument;
521  $manuscriptXmlDom->loadXML($manuscriptXml);
522  $xpath = new DOMXpath($manuscriptXmlDom);
523 
524  foreach ($elementsPath as $elementPath) {
525  $elements = $xpath->query($elementPath);
526  foreach ($elements as $element) {
527  $element->parentNode->removeChild($element);
528  }
529  }
530  return $manuscriptXmlDom;
531  }
532 
537  function getSubmission() {
538  return $this->getAuthorizedContextObject(ASSOC_TYPE_SUBMISSION);
539  }
540 
545  function getPlugin() {
546  return $this->_plugin;
547  }
548 
553  function getGalley() {
554  return $this->getAuthorizedContextObject(ASSOC_TYPE_REPRESENTATION);
555  }
556 
557 
558 }
PKPHandler\addRoleAssignment
addRoleAssignment($roleIds, $operations)
Definition: PKPHandler.inc.php:213
TextureHandler\authorize
authorize($request, &$args, $roleAssignments)
Definition: TextureHandler.inc.php:42
TextureHandler\$_plugin
$_plugin
Definition: TextureHandler.inc.php:23
TextureHandler\__construct
__construct()
Definition: TextureHandler.inc.php:28
TextureHandler\media
media($args, $request)
Definition: TextureHandler.inc.php:400
TextureHandler\_createDependentFile
_createDependentFile($genreId, $mediaData, $submission, $submissionFile, $user)
Definition: TextureHandler.inc.php:449
TextureHandler
Handle requests for Texture plugin.
Definition: TextureHandler.inc.php:18
TextureHandler\json
json($args, $request)
Definition: TextureHandler.inc.php:140
DAORegistry\getDAO
static & getDAO($name, $dbconn=null)
Definition: DAORegistry.inc.php:57
TextureHandler\createGalley
createGalley($args, $request)
Definition: TextureHandler.inc.php:73
TextureHandler\getPlugin
getPlugin()
Definition: TextureHandler.inc.php:548
TextureHandler\getGalley
getGalley()
Definition: TextureHandler.inc.php:556
PublicFileManager
Wrapper class for uploading files to a site/journal's public directory.
Definition: PublicFileManager.inc.php:18
GuzzleHttp\json_decode
json_decode($json, $assoc=false, $depth=512, $options=0)
Definition: guzzlehttp/guzzle/src/functions.php:301
TextureHandler\_buildManifestXMLFromDocument
_buildManifestXMLFromDocument($manuscriptXml, &$assets)
Definition: TextureHandler.inc.php:340
JSONMessage
Class to represent a JSON (Javascript Object Notation) message.
Definition: JSONMessage.inc.php:18
TextureArticleGalleyForm
Article galley editing form.
Definition: TextureArticleGalleyForm.inc.php:19
TextureHandler\editor
editor($args, $request)
Definition: TextureHandler.inc.php:103
PKPTemplateManager\getManager
static & getManager($request=null)
Definition: PKPTemplateManager.inc.php:1239
TextureHandler\getSubmission
getSubmission()
Definition: TextureHandler.inc.php:540
PKPHandler\getAuthorizedContextObject
& getAuthorizedContextObject($assocType)
Definition: PKPHandler.inc.php:174
SubmissionFileAccessPolicy
Base class to control (write) access to submissions and (read) access to submission files.
Definition: SubmissionFileAccessPolicy.inc.php:23
TextureHandler\createGalleyForm
createGalleyForm($args, $request)
Definition: TextureHandler.inc.php:55
TextureHandler\_updateManuscriptFile
_updateManuscriptFile($fileStage, $genreId, $resources, $submission, $submissionFile, $user)
Definition: TextureHandler.inc.php:484
PluginRegistry\getPlugin
static getPlugin($category, $name)
Definition: PluginRegistry.inc.php:85
Core\getCurrentDate
static getCurrentDate($ts=null)
Definition: Core.inc.php:63
PKPHandler\addPolicy
addPolicy($authorizationPolicy, $addToTop=false)
Definition: PKPHandler.inc.php:157
TextureHandler\_buildMediaInfo
_buildMediaInfo($request, $assets)
Definition: TextureHandler.inc.php:292
fatalError
if(!function_exists('import')) fatalError($reason)
Definition: functions.inc.php:32
Handler
Base request handler application class.
Definition: Handler.inc.php:18
GuzzleHttp\json_encode
json_encode($value, $options=0, $depth=512)
Definition: guzzlehttp/guzzle/src/functions.php:324
PKPLocale\requireComponents
static requireComponents()
Definition: PKPLocale.inc.php:374