/** * delete a News item * * @author Mark West * @param $args['sid'] ID of the item * @return bool true on success, false on failure */ public function delete($args) { // Argument check if (!isset($args['sid']) || !is_numeric($args['sid'])) { return LogUtil::registerArgsError(); } // Get the news story $item = ModUtil::apiFunc('News', 'user', 'get', array('sid' => $args['sid'])); if ($item == false) { return LogUtil::registerError($this->__('Error! No such article found.')); } $this->throwForbiddenUnless(SecurityUtil::checkPermission('News::', $item['cr_uid'] . '::' . $item['sid'], ACCESS_DELETE), LogUtil::getErrorMsgPermission()); if (!DBUtil::deleteObjectByID('news', $args['sid'], 'sid')) { return LogUtil::registerError($this->__('Error! Could not delete article.')); } // delete News images $modvars = $this->getVars(); if ($modvars['picupload_enabled'] && $item['pictures'] > 0) { News_ImageUtil::deleteImagesBySID($modvars['picupload_uploaddir'], $item['sid'], $item['pictures']); } // Let the calling process know that we have finished successfully return true; }
/** * This is a standard function that is called with the results of the * form supplied by News_admin_newitem() or News_user_newitem to create * a new item. * * @author Mark West * @param string 'title' the title of the news item * @param string 'language' the language of the news item * @param string 'hometext' the summary text of the news item * @param int 'hometextcontenttype' the content type of the summary text * @param string 'bodytext' the body text of the news item * @param int 'bodytextcontenttype' the content type of the body text * @param string 'notes' any administrator notes * @param int 'published_status' the published status of the item * @param int 'displayonindex' display the article on the index page * @return bool true */ public function create($args) { // Get parameters from whatever input we need $story = FormUtil::getPassedValue('story', isset($args['story']) ? $args['story'] : null, 'POST'); $files = News_ImageUtil::reArrayFiles(FormUtil::getPassedValue('news_files', null, 'FILES')); // Create the item array for processing $item = array( 'title' => $story['title'], 'urltitle' => isset($story['urltitle']) ? $story['urltitle'] : '', '__CATEGORIES__' => isset($story['__CATEGORIES__']) ? $story['__CATEGORIES__'] : null, '__ATTRIBUTES__' => isset($story['attributes']) ? News_Util::reformatAttributes($story['attributes']) : null, 'language' => isset($story['language']) ? $story['language'] : '', 'hometext' => isset($story['hometext']) ? $story['hometext'] : '', 'hometextcontenttype' => $story['hometextcontenttype'], 'bodytext' => isset($story['bodytext']) ? $story['bodytext'] : '', 'bodytextcontenttype' => $story['bodytextcontenttype'], 'notes' => $story['notes'], 'displayonindex' => isset($story['displayonindex']) ? $story['displayonindex'] : 0, 'allowcomments' => isset($story['allowcomments']) ? $story['allowcomments'] : 0, 'from' => isset($story['from']) ? $story['from'] : null, 'tonolimit' => isset($story['tonolimit']) ? $story['tonolimit'] : null, 'to' => isset($story['to']) ? $story['to'] : null, 'unlimited' => isset($story['unlimited']) && $story['unlimited'] ? true : false, 'weight' => isset($story['weight']) ? $story['weight'] : 0, 'action' => isset($story['action']) ? $story['action'] : self::ACTION_PREVIEW, 'sid' => isset($story['sid']) ? $story['sid'] : null, 'tempfiles' => isset($story['tempfiles']) ? $story['tempfiles'] : null, 'del_pictures' => isset($story['del_pictures']) ? $story['del_pictures'] : null, ); // convert user times to server times (TZ compensation) refs #181 // can't do the below because values are YYYY-MM-DD HH:MM:SS and DateUtil value is in seconds. // $item['from'] = $item['from'] + DateUtil::getTimezoneUserDiff(); // $item['to'] = $item['to'] + DateUtil::getTimezoneUserDiff(); // Disable the non accessible fields for non editors if (!SecurityUtil::checkPermission('News::', '::', ACCESS_ADD)) { $item['notes'] = ''; $item['displayonindex'] = 1; $item['allowcomments'] = 1; $item['from'] = null; $item['tonolimit'] = true; $item['to'] = null; $item['unlimited'] = true; $item['weight'] = 0; if ($item['action'] > self::ACTION_SUBMIT) { $item['action'] = self::ACTION_PREVIEW; } } // Validate the input $validationerror = News_Util::validateArticle($item); // check hooked modules for validation $sid = isset($item['sid']) ? $item['sid'] : null; $hookvalidators = $this->notifyHooks(new Zikula_ValidationHook('news.ui_hooks.articles.validate_edit', new Zikula_Hook_ValidationProviders()))->getValidators(); if ($hookvalidators->hasErrors()) { $validationerror .= $this->__('Error! Hooked content does not validate.') . "\n"; } // get all module vars $modvars = $this->getVars(); if (isset($files) && $modvars['picupload_enabled']) { list($files, $item) = News_ImageUtil::validateImages($files, $item); } else { $item['pictures'] = 0; } // story was previewed with uploaded pics if (isset($item['tempfiles'])) { $tempfiles = unserialize($item['tempfiles']); // delete files if requested if (isset($item['del_pictures'])) { foreach ($tempfiles as $key => $file) { if (in_array($file['name'], $item['del_pictures'])) { unset($tempfiles[$key]); News_ImageUtil::removePreviewImages(array($file)); } } } $files = array_merge($files, $tempfiles); $item['pictures'] += count($tempfiles); } // if the user has selected to preview the article we then route them back // to the new function with the arguments passed here if ($item['action'] == self::ACTION_PREVIEW || $validationerror !== false) { // log the error found if any if ($validationerror !== false) { LogUtil::registerError(nl2br($validationerror)); } if ($item['pictures'] > 0) { $tempfiles = News_ImageUtil::tempStore($files); $item['tempfiles'] = serialize($tempfiles); } // back to the referer form SessionUtil::setVar('newsitem', $item); $this->redirect(ModUtil::url('News', 'user', 'newitem')); } else { // As we're not previewing the item let's remove it from the session SessionUtil::delVar('newsitem'); } // Confirm authorization code. $this->checkCsrfToken(); if (!isset($item['sid']) || empty($item['sid'])) { // Create the news story $sid = ModUtil::apiFunc('News', 'user', 'create', $item); if ($sid != false) { // Success LogUtil::registerStatus($this->__('Done! Created new article.')); // Let any hooks know that we have created a new item $this->notifyHooks(new Zikula_ProcessHook('news.ui_hooks.articles.process_edit', $sid, new Zikula_ModUrl('News', 'User', 'display', ZLanguage::getLanguageCode(), array('sid' => $sid)))); $this->notify($item); // send notification email } else { // fail! story not created throw new Zikula_Exception_Fatal($this->__('Story not created for unknown reason (Api failure).')); return false; } } else { // update the draft $result = ModUtil::apiFunc('News', 'admin', 'update', $item); if ($result) { LogUtil::registerStatus($this->__('Story Updated.')); } else { // fail! story not updated throw new Zikula_Exception_Fatal($this->__('Story not updated for unknown reason (Api failure).')); return false; } } // clear respective cache ModUtil::apiFunc('News', 'user', 'clearItemCache', $item); if (isset($files) && $modvars['picupload_enabled']) { $resized = News_ImageUtil::resizeImages($sid, $files); // resize and move the uploaded pics if (isset($item['tempfiles'])) { News_ImageUtil::removePreviewImages($tempfiles); // remove any preview images } LogUtil::registerStatus($this->_fn('%1$s out of %2$s picture was uploaded and resized.', '%1$s out of %2$s pictures were uploaded and resized.', $item['pictures'], array($resized, $item['pictures']))); if (($item['action'] >= self::ACTION_SAVEDRAFT) && ($resized <> $item['pictures'])) { LogUtil::registerStatus($this->_fn('Article now has draft status, since the picture was not uploaded.', 'Article now has draft status, since not all pictures were uploaded.', $item['pictures'], array($resized, $item['pictures']))); } } // release pagelock if (ModUtil::available('PageLock')) { ModUtil::apiFunc('PageLock', 'user', 'releaseLock', array('lockName' => "Newsnews{$item['sid']}")); } if ($item['action'] == self::ACTION_SAVEDRAFT_RETURN) { SessionUtil::setVar('newsitem', $item); $this->redirect(ModUtil::url('News', 'user', 'newitem')); } $this->redirect(ModUtil::url('News', 'user', 'view')); }
/** * Move images to temp location so they can be recaptured later * @param array $files */ public static function tempStore($files) { $destination = ModUtil::getVar('News', 'picupload_uploaddir') . '/' . "PREVIEW"; if (!is_dir($destination)) { News_ImageUtil::mkdir($destination); } $newfiles = array(); foreach ($files as $key => $file) { if ($file['resize']) { $filename = $file['name']; $uploadfile = $file['tmp_name']; $file['tmp_name'] = DataUtil::formatForOS("$destination/$filename"); move_uploaded_file($uploadfile, $file['tmp_name']); $newfiles[] = $file; } } return $newfiles; }
/** * A function to handle bulk actions in the admin interface * * @param array 'articles' array of article ids to process * @param int 'bulkaction' the action to take * @return bool true */ public function processbulkaction() { $this->checkCsrfToken(); $this->throwForbiddenUnless(SecurityUtil::checkPermission('News::', '::', ACCESS_DELETE), LogUtil::getErrorMsgPermission()); $articles = FormUtil::getPassedValue('news_selected_articles', array(), 'POST'); $bulkaction = (int)FormUtil::getPassedValue('news_bulkaction_select', 0, 'POST'); $cat_data = FormUtil::getPassedValue('news_bulkaction_categorydata', '', 'POST'); if ($bulkaction >= 1 && $bulkaction <= 5) { $actionmap = array( // these indices are not constants, just unrelated integers 1 => __('Delete'), 2 => __('Archive'), 3 => __('Publish'), 4 => __('Reject'), 5 => __('Change categories')); $updateresult = array( 'successful' => array(), 'failed' => array()); switch ($bulkaction) { case 1: // delete foreach ($articles as $article) { if (DBUtil::deleteObjectByID('news', $article, 'sid')) { // assume max pictures. if less, errors are supressed by @ News_ImageUtil::deleteImagesBySID($this->getVar('picupload_uploaddir'), $article, $this->getVar('picupload_maxpictures')); $updateresult['successful'][] = $article; } else { $updateresult['failed'][] = $article; } } break; case 5: // change categories $obj = array(); $obj['__CATEGORIES__'] = json_decode($cat_data, true); unset($obj['__CATEGORIES__']['submit']); foreach ($articles as $article) { $obj['sid'] = $article; if (DBUtil::updateObject($obj, 'news', '', 'sid')) { $updateresult['successful'][] = $article; } else { $updateresult['failed'][] = $article; } } break; default: // archive, publish or reject $statusmap = array( 2 => News_Api_User::STATUS_ARCHIVED, 3 => News_Api_User::STATUS_PUBLISHED, 4 => News_Api_User::STATUS_REJECTED ); foreach ($articles as $article) { $obj = array( 'sid' => $article, 'published_status' => $statusmap[$bulkaction] ); if (DBUtil::updateObject($obj, 'news', '', 'sid')) { $updateresult['successful'][] = $article; } else { $updateresult['failed'][] = $article; } } } $updateresult['successful']['list'] = implode(', ', $updateresult['successful']); $updateresult['failed']['list'] = implode(', ', $updateresult['failed']); LogUtil::registerStatus($this->__f('Processed Bulk Action. Action: %s.', $actionmap[$bulkaction])); if (!empty($updateresult['successful']['list'])) { LogUtil::registerStatus($this->__f('Success with articles: %s', $updateresult['successful']['list'])); } if (!empty($updateresult['failed']['list'])) { LogUtil::registerError($this->__f('Failed with articles: %s', $updateresult['failed']['list'])); } } else { LogUtil::registerError($this->__('Error! Wrong bulk action.')); } return $this->redirect(ModUtil::url('News', 'admin', 'view')); }