/** * Approve publication * * @return void */ public function approveTask() { // Incoming $pid = $this->_id ? $this->_id : Request::getInt('id', 0); $vid = Request::getInt('vid', 0); // Load publication model $this->_pub = new \Components\Publications\Models\Publication($pid, NULL, $vid); if (!$this->_pub->exists()) { throw new Exception(Lang::txt('COM_PUBLICATIONS_NOT_FOUND'), 404); } // Check authorization if (!$this->_pub->access('curator')) { if (User::isGuest()) { $this->_msg = Lang::txt('COM_PUBLICATIONS_CURATION_LOGIN'); $this->_login(); return; } throw new Exception(Lang::txt('COM_PUBLICATIONS_CURATION_ERROR_UNAUTHORIZED'), 403); } $this->_pub->version->set('state', 1); $this->_pub->version->set('accepted', Date::toSql()); $this->_pub->version->set('reviewed', Date::toSql()); $this->_pub->version->set('reviewed_by', User::get('id')); // Archive (mkAIP) if no grace period and not previously archived if (!$this->getError() && !$this->config->get('graceperiod', 0) && $this->_pub->version->doi && \Components\Publications\Helpers\Utilities::mkAip($this->_pub->version) && !$this->_pub->archived()) { $this->_pub->version->set('archived', Date::toSql()); } // Set curation $this->_pub->setCuration(); $curation = json_encode($this->_pub->_curationModel->_manifest); //$curation = $this->_pub->masterType()->curation; // Get manifest version $versionNumber = $this->_pub->_curationModel->checkCurationVersion(); // Store curation manifest $this->_pub->version->set('curation', $curation); $this->_pub->version->set('curation_version_id', $versionNumber); if (!$this->_pub->version->store()) { throw new Exception(Lang::txt('PLG_PROJECTS_PUBLICATIONS_PUBLICATION_FAILED'), 403); } // Get DOI service $doiService = new \Components\Publications\Models\Doi($this->_pub); if ($this->_pub->version->doi) { $doiService->update($this->_pub->version->doi, true); } // Mark as curated $this->_pub->saveParam('curated', 1); // On after status change $this->onAfterStatusChange(); $message = $this->getError() ? $this->getError() : Lang::txt('COM_PUBLICATIONS_CURATION_SUCCESS_APPROVED'); $class = $this->getError() ? 'error' : 'success'; // Redirect to main listing App::redirect(Route::url('index.php?option=' . $this->_option . '&controller=curation'), $message, $class); return; }
/** * Archive publications beyond grace period * * @param object $job \Components\Cron\Models\Job * @return boolean */ public function runMkAip(\Components\Cron\Models\Job $job) { $database = \App::get('db'); $config = Component::params('com_publications'); require_once PATH_CORE . DS . 'components' . DS . 'com_publications' . DS . 'helpers' . DS . 'utilities.php'; require_once PATH_CORE . DS . 'components' . DS . 'com_publications' . DS . 'tables' . DS . 'version.php'; require_once PATH_CORE . DS . 'components' . DS . 'com_projects' . DS . 'helpers' . DS . 'html.php'; // Check that mkAIP script exists if (!\Components\Publications\Helpers\Utilities::archiveOn()) { return; } // Check for grace period $gracePeriod = $config->get('graceperiod', 0); if (!$gracePeriod) { // If no grace period, this cron is unnecessary (archived as approval) return; } $aipBasePath = trim($config->get('aip_path', NULL), DS); $aipBasePath = $aipBasePath && is_dir(DS . $aipBasePath) ? DS . $aipBasePath : NULL; // Check for base path if (!$aipBasePath) { $this->setError('Missing archival base directory'); return; } // Get all unarchived publication versions $query = "SELECT V.*, C.id as id, V.id as version_id "; $query .= " FROM #__publication_versions as V, #__publications as C "; $query .= " WHERE C.id=V.publication_id AND V.state=1 "; $query .= " AND V.doi IS NOT NULL "; $query .= " AND V.accepted IS NOT NULL AND V.accepted !='0000-00-00 00:00:00' "; $query .= " AND (V.archived IS NULL OR V.archived ='0000-00-00 00:00:00') "; $database->setQuery($query); if (!($rows = $database->loadObjectList())) { return true; } // Start email message $subject = Lang::txt('Update on recently archived publications'); $body = Lang::txt('The following publications passed the grace period and were archived:') . "\n"; $aipGroup = $config->get('aip_group'); $counter = 0; foreach ($rows as $row) { // Grace period unexpired? $monthFrom = Date::of($row->accepted . '+1 month')->toSql(); if (strtotime($monthFrom) > strtotime(Date::of('now'))) { continue; } // Load version $pv = new \Components\Publications\Tables\Version($database); if (!$pv->load($row->version_id)) { continue; } // Create aip path $doiParts = explode('/', $row->doi); $aipName = count($doiParts) > 1 ? $doiParts[0] . '__' . $doiParts[1] : ''; // Archival package exists? if ($aipBasePath && $aipName && is_dir($aipBasePath . DS . $aipName)) { // Save approved date and archive date $pv->archived = $pv->accepted; $pv->store(); // Do not overwrite existing archives !! continue; } // Run mkAIP and save archived date if (\Components\Publications\Helpers\Utilities::mkAip($row)) { $pv->archived = Date::toSql(); $pv->store(); $counter++; $body .= $row->title . ' v.' . $row->version_label . ' (id #' . $row->id . ')' . "\n"; } } // Email update to admins if ($counter > 0 && $aipGroup) { // Set email config $from = array('name' => Config::get('fromname') . ' ' . Lang::txt('Publications'), 'email' => Config::get('mailfrom'), 'multipart' => md5(date('U'))); $admins = \Components\Projects\Helpers\Html::getGroupMembers($aipGroup); // Build message if (!empty($admins)) { foreach ($admins as $admin) { // Get the user's account $user = User::getInstance($admin); if (!$user->get('id')) { continue; } $message = new \Hubzero\Mail\Message(); $message->setSubject($subject)->addFrom($from['email'], $from['name'])->addTo($user->get('email'), $user->get('name'))->addHeader('X-Component', 'com_publications')->addHeader('X-Component-Object', 'publications'); $message->addPart($body, 'text/plain'); $message->send(); } } } // All done return true; }
$citation = \Components\Citations\Helpers\Format::formatReference($cite); } // Get creator name $creator = $this->pub->creator('name') . ' (' . $this->pub->creator('username') . ')'; // Version status $status = $this->pub->getStatusName(); $class = $this->pub->getStatusCss(); // Is draft ready? $complete = $this->pub->curation('complete'); $showCitations = $this->pub->_category->_params->get('show_citations', 1); $allowUnpublish = $this->pub->_category->_params->get('option_unpublish', 0); // We also need a citations block $blockActive = $this->pub->curation()->blockExists('citations'); $showCitations = $blockActive ? $showCitations : 0; // Check if publication is within grace period (published status) $allowArchive = \Components\Publications\Helpers\Utilities::archiveOn(); $archiveDate = $this->pub->futureArchivalDate(); $revertAllowed = $this->pub->config('graceperiod'); if ($revertAllowed && $this->pub->accepted()) { $monthFrom = Date::of($this->pub->accepted() . '+1 month')->toSql(); if (strtotime($monthFrom) < Date::toUnix()) { $revertAllowed = 0; } } ?> <form action="<?php echo Route::url($this->pub->link('edit')); ?> " method="post" id="plg-form" enctype="multipart/form-data"> <?php
/** * Saves a publication * Redirects to main listing * * @param boolean $redirect * @return void */ public function saveTask($redirect = false) { // Check for request forgeries Request::checkToken(); // Incoming $id = Request::getInt('id', 0); $action = Request::getVar('admin_action', ''); $published_up = Request::getVar('published_up', ''); $version = Request::getVar('version', 'default'); // Is this a new publication? Cannot create via back-end $isnew = $id ? 0 : 1; if (!$id) { App::redirect(Route::url('index.php?option=' . $this->_option . '&controller=' . $this->_controller, false), Lang::txt('COM_PUBLICATIONS_ERROR_LOAD_PUBLICATION'), 'error'); return; } // Load publication model $this->model = new Models\Publication($id, $version); if (!$this->model->exists()) { throw new Exception(Lang::txt('COM_PUBLICATIONS_NOT_FOUND'), 404); } // Checkin resource $this->model->publication->checkin(); // Set redirect URL $url = Route::url('index.php?option=' . $this->_option . '&controller=' . $this->_controller . '&task=edit' . '&id[]=' . $id . '&version=' . $version, false); $authors = $this->model->authors(); $project = $this->model->project(); $this->model->setCuration(); $requireDoi = isset($this->model->_curationModel->_manifest->params->require_doi) ? $this->model->_curationModel->_manifest->params->require_doi : 0; // Incoming updates $title = trim(Request::getVar('title', '', 'post')); $title = htmlspecialchars($title); $abstract = trim(Request::getVar('abstract', '', 'post')); $abstract = htmlspecialchars(\Hubzero\Utility\Sanitize::clean($abstract)); $description = trim(Request::getVar('description', '', 'post', 'none', 2)); $release_notes = stripslashes(trim(Request::getVar('release_notes', '', 'post', 'none', 2))); $group_owner = Request::getInt('group_owner', 0, 'post'); $published_up = trim(Request::getVar('published_up', '', 'post')); $published_down = trim(Request::getVar('published_down', '', 'post')); $state = Request::getInt('state', 0); $metadata = ''; $activity = ''; // Save publication record $this->model->publication->alias = trim(Request::getVar('alias', '', 'post')); $this->model->publication->category = trim(Request::getInt('category', 0, 'post')); $this->model->publication->access = Request::getInt('access', 0, 'post'); if (!$project->get('owned_by_group')) { $this->model->publication->group_owner = $group_owner; } $this->model->publication->store(); // Get metadata if (isset($_POST['nbtag'])) { $category = $this->model->category(); $fields = array(); if (trim($category->customFields) != '') { $fs = explode("\n", trim($category->customFields)); foreach ($fs as $f) { $fields[] = explode('=', $f); } } $nbtag = Request::getVar('nbtag', array(), 'request', 'array'); foreach ($nbtag as $tagname => $tagcontent) { $tagcontent = trim(stripslashes($tagcontent)); if ($tagcontent != '') { $metadata .= "\n" . '<nb:' . $tagname . '>' . $tagcontent . '</nb:' . $tagname . '>' . "\n"; } else { foreach ($fields as $f) { if ($f[0] == $tagname && end($f) == 1) { echo Helpers\Html::alert(Lang::txt('COM_PUBLICATIONS_REQUIRED_FIELD_CHECK', $f[1])); exit; } } } } } // Save incoming $this->model->version->title = $title; $this->model->version->abstract = \Hubzero\Utility\String::truncate($abstract, 250); $this->model->version->description = $description; $this->model->version->metadata = $metadata; $this->model->version->release_notes = $release_notes; $this->model->version->license_text = trim(Request::getVar('license_text', '', 'post')); $this->model->version->license_type = Request::getInt('license_type', 0, 'post'); $this->model->version->access = Request::getInt('access', 0, 'post'); // Get DOI service $doiService = new Models\Doi($this->model); // DOI manually entered? $doi = trim(Request::getVar('doi', '', 'post')); if ($doi && (!$this->model->version->doi || !preg_match("/" . $doiService->_configs->shoulder . "/", $this->model->version->doi))) { $this->model->version->doi = $doi; } $this->model->version->published_up = $published_up ? Date::of($published_up, Config::get('offset'))->toSql() : '0000-00-00 00:00:00'; $this->model->version->published_down = $published_down && trim($published_down) != 'Never' ? Date::of($published_down, Config::get('offset'))->toSql() : '0000-00-00 00:00:00'; // Determine action (if status is flipped) if ($this->model->version->state != $state) { switch ($state) { case 1: $action = $this->model->version->state == 0 ? 'republish' : 'publish'; break; case 0: $action = 'unpublish'; break; case 3: case 4: $action = 'revert'; break; case 7: $action = 'wip'; break; } $this->model->version->state = $state; } // Update DOI with latest information if ($this->model->version->doi && !$action) { // Update DOI if locally issued if (preg_match("/" . $doiService->_configs->shoulder . "/", $this->model->version->doi)) { $doiService->update($this->model->version->doi, true); } } // Incoming tags $tags = Request::getVar('tags', '', 'post'); // Save the tags $rt = new Helpers\Tags($this->database); $rt->tag_object(User::get('id'), $id, $tags, 1, true); // Email config $pubtitle = \Hubzero\Utility\String::truncate($this->model->version->title, 100); $subject = Lang::txt('Version') . ' ' . $this->model->version->version_label . ' ' . Lang::txt('COM_PUBLICATIONS_OF') . ' ' . strtolower(Lang::txt('COM_PUBLICATIONS_PUBLICATION')) . ' "' . $pubtitle . '" '; $sendmail = 0; $message = rtrim(\Hubzero\Utility\Sanitize::clean(Request::getVar('message', ''))); $output = Lang::txt('COM_PUBLICATIONS_SUCCESS_SAVED_ITEM'); // Admin actions if ($action) { $output = ''; switch ($action) { case 'publish': case 'republish': // Unset the published_down timestamp if publishing $this->model->version->published_down = '0000-00-00 00:00:00'; $activity = $action == 'publish' ? Lang::txt('COM_PUBLICATIONS_ACTIVITY_ADMIN_PUBLISHED') : Lang::txt('COM_PUBLICATIONS_ACTIVITY_ADMIN_REPUBLISHED'); $subject .= $action == 'publish' ? Lang::txt('COM_PUBLICATIONS_MSG_ADMIN_PUBLISHED') : Lang::txt('COM_PUBLICATIONS_MSG_ADMIN_REPUBLISHED'); $this->model->version->state = 1; // Is service enabled? - Issue/update a DOI if ($doiService->on()) { if ($this->model->version->doi && preg_match("/" . $doiService->_configs->shoulder . "/", $this->model->version->doi)) { // Update $doiService->update($this->model->version->doi, true); if ($doiService->getError()) { $this->setError($doiService->getError()); } } elseif ($requireDoi) { // Register $doi = $doiService->register(true); if (!$doi) { App::redirect($url, Lang::txt('COM_PUBLICATIONS_ERROR_DOI') . ' ' . $doiService->getError(), 'error'); return; } else { $this->model->version->doi = $doi; } } } // Save date accepted if ($action == 'publish') { $this->model->version->accepted = Date::toSql(); $this->model->version->published_up = $published_up ? Date::of($published_up, Config::get('offset'))->toSql() : Date::toSql(); // Get and save manifest and its version $versionNumber = $this->model->_curationModel->checkCurationVersion(); $this->model->version->set('curation', json_encode($this->model->_curationModel->_manifest)); $this->model->version->set('curation_version_id', $versionNumber); // Check if publication is within grace period (published status) $gracePeriod = $this->config->get('graceperiod', 0); $allowArchive = $gracePeriod ? false : true; if ($allowArchive && $this->model->version->accepted && $this->model->version->accepted != '0000-00-00 00:00:00') { $monthFrom = Date::of($this->model->version->accepted . '+1 month')->toSql(); if (strtotime($monthFrom) < Date::toUnix()) { $allowArchive = true; } } // Run mkAIP if no grace period set or passed if (!$this->getError() && $this->model->version->doi && $allowArchive == true && (!$this->model->version->archived || $this->model->version->archived == '0000-00-00 00:00:00') && Helpers\Utilities::mkAip($this->model->version)) { $this->model->version->archived = Date::toSql(); } } if (!$this->getError()) { $output .= ' ' . Lang::txt('COM_PUBLICATIONS_ITEM') . ' '; $output .= $action == 'publish' ? Lang::txt('COM_PUBLICATIONS_MSG_ADMIN_PUBLISHED') : Lang::txt('COM_PUBLICATIONS_MSG_ADMIN_REPUBLISHED'); } break; case 'revert': // What is this? This sets it to the state it's alreayd in. //$this->model->version->state = $state ? $state : 4; $this->model->version->state = 3; $activity = Lang::txt('COM_PUBLICATIONS_ACTIVITY_ADMIN_REVERTED'); $subject .= Lang::txt('COM_PUBLICATIONS_MSG_ADMIN_REVERTED'); $output .= ' ' . Lang::txt('COM_PUBLICATIONS_ITEM') . ' '; $output .= Lang::txt('COM_PUBLICATIONS_MSG_ADMIN_REVERTED'); break; case 'unpublish': $this->model->version->state = 0; $this->model->version->published_down = Date::toSql(); $activity = Lang::txt('COM_PUBLICATIONS_ACTIVITY_ADMIN_UNPUBLISHED'); $subject .= Lang::txt('COM_PUBLICATIONS_MSG_ADMIN_UNPUBLISHED'); $output .= ' ' . Lang::txt('COM_PUBLICATIONS_ITEM') . ' '; $output .= Lang::txt('COM_PUBLICATIONS_MSG_ADMIN_UNPUBLISHED'); break; case 'wip': $activity = Lang::txt('COM_PUBLICATIONS_ACTIVITY_ADMIN_REQUESTED_CHANGES'); $subject .= Lang::txt('COM_PUBLICATIONS_MSG_ADMIN_REQUESTED_CHANGES'); $output .= ' ' . Lang::txt('COM_PUBLICATIONS_ITEM') . ' '; $output .= Lang::txt('COM_PUBLICATIONS_MSG_ADMIN_REQUESTED_CHANGES'); break; } } // Updating entry if anything changed if (!$this->getError()) { $this->model->version->modified = Date::toSql(); $this->model->version->modified_by = User::get('id'); // Store content if (!$this->model->version->store()) { App::redirect($url, $this->model->version->getError(), 'error'); return; } elseif ($action) { // Add activity $activity .= ' ' . strtolower(Lang::txt('version')) . ' ' . $this->model->version->version_label . ' ' . Lang::txt('COM_PUBLICATIONS_OF') . ' ' . strtolower(Lang::txt('publication')) . ' "' . $pubtitle . '" '; // Build return url $link = '/projects/' . $project->get('alias') . '/publications/' . $id . '/?version=' . $this->model->version->version_number; if ($action != 'message' && !$this->getError()) { $aid = $project->recordActivity($activity, $id, $pubtitle, $link, 'publication', 0, $admin = 1); $sendmail = $this->config->get('email') ? 1 : 0; // Append comment to activity if ($message && $aid) { require_once PATH_CORE . DS . 'components' . DS . 'com_projects' . DS . 'tables' . DS . 'comment.php'; $objC = new \Components\Projects\Tables\Comment($this->database); $comment = \Hubzero\Utility\String::truncate($message, 250); $comment = \Hubzero\Utility\Sanitize::stripAll($comment); $objC->itemid = $aid; $objC->tbl = 'activity'; $objC->parent_activity = $aid; $objC->comment = $comment; $objC->admin = 1; $objC->created = Date::toSql(); $objC->created_by = User::get('id'); $objC->store(); // Get new entry ID if (!$objC->id) { $objC->checkin(); } if ($objC->id) { $what = Lang::txt('COM_PROJECTS_AN_ACTIVITY'); $curl = Route::url($project->link('feed')) . '#tr_' . $aid; // same-page link $caid = $project->recordActivity(Lang::txt('COM_PROJECTS_COMMENTED') . ' ' . Lang::txt('COM_PROJECTS_ON') . ' ' . $what, $objC->id, $what, $curl, 'quote', 0, 1); // Store activity ID if ($caid) { $objC->activityid = $aid; $objC->store(); } } } } } } // Save parameters $params = Request::getVar('params', '', 'post'); if (is_array($params)) { foreach ($params as $k => $v) { $this->model->version->saveParam($this->model->version->id, $k, $v); } } // Do we have a message to send? if ($message) { $subject .= ' - ' . Lang::txt('COM_PUBLICATIONS_MSG_ADMIN_NEW_MESSAGE'); $sendmail = 1; $output .= ' ' . Lang::txt('COM_PUBLICATIONS_MESSAGE_SENT'); } // Send email if ($sendmail && !$this->getError()) { // Get ids of publication authors with accounts $notify = $this->model->table('Author')->getAuthors($this->model->version->id, 1, 1, 1, true); $notify[] = $this->model->version->created_by; $notify = array_unique($notify); $this->_emailContributors($subject, $message, $notify, $action); } // Append any errors if ($this->getError()) { $output .= ' ' . $this->getError(); } // Redirect to edit view? if ($redirect) { App::redirect(Route::url('index.php?option=' . $this->_option . '&controller=' . $this->_controller . '&task=edit' . '&id[]=' . $id . '&version=' . $this->model->get('version_number'), false), $output); } else { App::redirect(Route::url('index.php?option=' . $this->_option . '&controller=' . $this->_controller, false), $output); } return; }