Esempio n. 1
0
    /**
     * This is the Ajax function that is called with the results of the
     * form supplied by news_<user/admin>_new() to create a new draft item
     * The following parameters are received in an array 'story'!
     *
     * @param string 'title' the title of the news item
     *
     * @author Erik Spaan
     * @return array(output, etc) with output being a rendered template or a simple text and action the performed action
     */
    public function savedraft()
    {
        $this->checkAjaxToken();
        $story = $this->request->getPost()->get('story', null);

        // cannot process file inputs (pictures) via ajax
        // File inputs are skipped as they cannot be serialized and sent using only JavaScript.
        // @see http://api.prototypejs.org/dom/Form/serialize/
        // @see http://www.openjs.com/articles/ajax/ajax_file_upload/

        $output = '';
        $slug = '';
        $fullpermalink = '';
        $showslugedit = false;
        
        // Validate the input
        $validationerror = News_Util::validateArticle($story);
        // check hooked modules for validation
        $sid = isset($story['sid']) ? $story['sid'] : null;
        $hookvalidators = $this->notifyHooks('news.ui_hooks.articles.validate_edit', $story, $sid, array(), new Zikula_Hook_ValidationProviders())->getData();
        if ($hookvalidators->hasErrors()) {
            $validationerror .= $this->__('Error! Hooked content does not validate.') . "\n";
        }
        if ($validationerror) {
            return new Zikula_Response_Ajax_BadData($validationerror);
        }

        $newitem = array(
            'sid' => isset($story['sid']) ? $story['sid'] : null,
            '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' => isset($story['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,
            'tempfiles' => isset($story['tempfiles']) ? $story['tempfiles'] : null,
            'pictures' => isset($story['pictures']) ? $story['pictures'] : 0,
            'del_pictures' => isset($story['del_pictures']) ? $story['del_pictures'] : null,
            'published_status' => isset($story['published_status']) ? $story['published_status'] : News_Api_User::STATUS_DRAFT,
            );

        // get all module vars
        $modvars = $this->getVars();

        // Check  if the article is already saved as draft
        if (isset($story['sid']) && $story['sid'] > 0) {
            // Get the current news article
            $item = ModUtil::apiFunc('News', 'User', 'get', array('sid' => $story['sid']));
            if ($item == false) {
                throw new Zikula_Exception_NotFound($this->__('Error! No such article found.'));
            }
            // Security check
            $this->throwForbiddenUnless(SecurityUtil::checkPermission('News::', "{$item['cr_uid']}::{$story['sid']}", ACCESS_EDIT));

            if (!ModUtil::apiFunc('News', 'admin', 'update', $newitem)) {
                $output = DataUtil::formatForDisplayHTML($this->__('Error! Could not save your changes.'));
            } else {
                $output = $this->__f('Draft updated at %s', DateUtil::getDatetime_Time('', '%H:%M'));
                // Return the permalink (domain shortened) and the slug of the permalink
                $slug = $item['urltitle'];
                $fullpermalink = DataUtil::formatForDisplayHTML(ModUtil::url('News', 'user', 'display', array('sid' => $story['sid'])));
                // Only show "edit the slug" if the shorturls are active
                $showslugedit = (System::getVar('shorturls', false));
            }
            $sid = $story['sid'];
        } else {
            // Create a first draft version of the story
            $sid = ModUtil::apiFunc('News', 'User', 'create', $newitem);
            if (!empty($sid)) {
                // Success and now reload the news story
                $item = ModUtil::apiFunc('News', 'User', 'get', array('sid' => $sid));
                if ($item == false) {
                    throw new Zikula_Exception_NotFound($this->__('Error! No such article found.'));
                } else {
                    // Return the Draft creation date
                    $output = $this->__f('Draft saved at %s', DateUtil::getDatetime_Time($item['cr_date'], '%H:%M'));
                    // Return the permalink (domain shortened) and the slug of the permalink
                    $slug = $item['urltitle'];
                    $fullpermalink = DataUtil::formatForDisplayHTML(ModUtil::url('News', 'user', 'display', array('sid' => $sid)));
                    // Only show "edit the slug" if the shorturls are active
                    $showslugedit = (System::getVar('shorturls', false));
                }
            } else {
                $output = DataUtil::formatForDisplayHTML($this->__('Error! Could not save your changes.'));
            }
        }

        //lock the page so others cannot edit it
        if (ModUtil::available('PageLock')) {
            $returnUrl = ModUtil::url('News', 'admin', 'view');
            ModUtil::apiFunc('PageLock', 'user', 'pageLock', array(
                'lockName' => "Newsnews{$sid}",
                'returnUrl' => $returnUrl));
        }

        return new Zikula_Response_Ajax(array(
            'result' => $output,
            'sid' => $sid,
            'slug' => $slug,
            'fullpermalink' => $fullpermalink,
            'showslugedit' => $showslugedit));
    }
Esempio n. 2
0
    /**
     * 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'));
    }
Esempio n. 3
0
    /**
     * view items
     * @param int 'startnum' starting number for paged output
     * @author Mark West
     * @return string HTML string
     */
    public function view($args)
    {
        $this->throwForbiddenUnless(SecurityUtil::checkPermission('News::', '::', ACCESS_EDIT), LogUtil::getErrorMsgPermission());

        // initialize sort array - used to display sort classes and urls
        $sort = array();
        $fields = array('sid', 'weight', 'from'); // possible sort fields
        foreach ($fields as $field) {
            $sort['class'][$field] = 'z-order-unsorted'; // default values
        }

        $startnum = FormUtil::getPassedValue('startnum', isset($args['startnum']) ? $args['startnum'] : null, 'GETPOST');
        $news_status = FormUtil::getPassedValue('news_status', isset($args['news_status']) ? $args['news_status'] : null, 'GETPOST');
        $language = FormUtil::getPassedValue('news_language', isset($args['news_language']) ? $args['news_language'] : null, 'GETPOST');
        $purge = FormUtil::getPassedValue('purge', false, 'GET');
        $order = FormUtil::getPassedValue('order', isset($args['order']) ? $args['order'] : 'from', 'GETPOST');
        $original_sdir = FormUtil::getPassedValue('sdir', isset($args['sdir']) ? $args['sdir'] : 1, 'GETPOST');

        $this->view->assign('startnum', $startnum);
        $this->view->assign('order', $order);
        $this->view->assign('sdir', $original_sdir);
        $this->view->assign('selected_language', (isset($language)) ? $language : '');
        
        $sdir = $original_sdir ? 0 : 1; //if true change to false, if false change to true
        // change class for selected 'orderby' field to asc/desc
        if ($sdir == 0) {
            $sort['class'][$order] = 'z-order-desc';
            $orderdir = 'DESC';
        }
        if ($sdir == 1) {
            $sort['class'][$order] = 'z-order-asc';
            $orderdir = 'ASC';
        }
        $filtercats = FormUtil::getPassedValue('news', null, 'GETPOST');
        $filtercats_serialized = FormUtil::getPassedValue('filtercats_serialized', false, 'GET');
        $filtercats = $filtercats_serialized ? unserialize($filtercats_serialized) : $filtercats;
        $catsarray = News_Util::formatCategoryFilter($filtercats);

        // complete initialization of sort array, adding urls
        foreach ($fields as $field) {
            $sort['url'][$field] = ModUtil::url('News', 'admin', 'view', array(
                        'news_status' => $news_status,
                        'news_language' => $language,
                        'filtercats_serialized' => serialize($filtercats),
                        'order' => $field,
                        'sdir' => $sdir));
        }
        $this->view->assign('sort', $sort);

        $this->view->assign('filter_active', (!isset($language) && !isset($news_status) && empty($filtercats)) ? false : true);

        if ($purge) {
            if (ModUtil::apiFunc('News', 'admin', 'purgepermalinks')) {
                LogUtil::registerStatus($this->__('Done! Purged permalinks.'));
            } else {
                LogUtil::registerError($this->__('Error! Could not purge permalinks.'));
            }
            return $this->redirect(strpos(System::serverGetVar('HTTP_REFERER'), 'purge') ? ModUtil::url('News', 'admin', 'view') : System::serverGetVar('HTTP_REFERER'));
        }

        // clean the session preview data
        SessionUtil::delVar('newsitem');

        // get module vars for later use
        $modvars = $this->getVars();

        if ($modvars['enablecategorization']) {
            $catregistry = CategoryRegistryUtil::getRegisteredModuleCategories('News', 'news');
            $this->view->assign('catregistry', $catregistry);
        }

        $multilingual = System::getVar('multilingual', false);

        $now = DateUtil::getDatetime();
        $status = null;
        if (isset($news_status) && $news_status != '') {
            if ($news_status == 0) {
                $status = 0;
                $to = $now;
            } elseif ($news_status == 5) {
                // scheduled is actually the published status, but in the future
                $status = 0;
                $from = $now;
            } else {
                $status = $news_status;
            }
        }

        // Get all news stories
        $getallargs = array('startnum' => $startnum,
            'status' => $status,
            'numitems' => $modvars['itemsperadminpage'],
            'ignoreml' => true,
            'language' => $language,
            'order' => isset($order) ? $order : 'from',
            'orderdir' => isset($orderdir) ? $orderdir : 'DESC',
            'from' => isset($from) ? $from : null,
            'to' => isset($to) ? $to : null,
            'filterbydate' => false,
            'category' => null,
            'catfilter' => isset($catsarray) ? $catsarray : null,
            'catregistry' => isset($catregistry) ? $catregistry : null);
        $items = ModUtil::apiFunc('News', 'user', 'getall', $getallargs);
        $total_articles = ModUtil::apiFunc('News', 'user', 'countitems', $getallargs);

        // Set the possible status for later use
        $itemstatus = array(
            '' => $this->__('All'),
            News_Api_User::STATUS_PUBLISHED => $this->__('Published'),
            News_Api_User::STATUS_REJECTED => $this->__('Rejected'),
            News_Api_User::STATUS_PENDING => $this->__('Pending Review'),
            News_Api_User::STATUS_ARCHIVED => $this->__('Archived'),
            News_Api_User::STATUS_DRAFT => $this->__('Draft'),
            News_Api_User::STATUS_SCHEDULED => $this->__('Scheduled')
        );

        $newsitems = array();
        foreach ($items as $item)
        {
            $options = array();
            if (System::getVar('shorturls', false)) {
                $options[] = array('url' => ModUtil::url('News', 'user', 'display', array('sid' => $item['sid'], 'from' => $item['from'], 'urltitle' => $item['urltitle'])),
                    'image' => '14_layer_visible.png',
                    'title' => $this->__('View'));
            } else {
                $options[] = array('url' => ModUtil::url('News', 'user', 'display', array('sid' => $item['sid'])),
                    'image' => '14_layer_visible.png',
                    'title' => $this->__('View'));
            }

            if (SecurityUtil::checkPermission('News::', "{$item['cr_uid']}::{$item['sid']}", ACCESS_EDIT)) {
                if ($item['published_status'] == News_Api_User::STATUS_PENDING) {
                    $options[] = array('url' => ModUtil::url('News', 'admin', 'modify', array('sid' => $item['sid'])),
                        'image' => 'editcut.png',
                        'title' => $this->__('Review'));
                } else {
                    $options[] = array('url' => ModUtil::url('News', 'admin', 'modify', array('sid' => $item['sid'])),
                        'image' => 'xedit.png',
                        'title' => $this->__('Edit'));
                }

                if (($item['published_status'] != News_Api_User::STATUS_PENDING &&
                        (SecurityUtil::checkPermission('News::', "{$item['cr_uid']}::{$item['sid']}", ACCESS_DELETE))) ||
                        SecurityUtil::checkPermission('News::', "{$item['cr_uid']}::{$item['sid']}", ACCESS_ADMIN)) {
                    $options[] = array('url' => ModUtil::url('News', 'admin', 'delete', array('sid' => $item['sid'])),
                        'image' => '14_layer_deletelayer.png',
                        'title' => $this->__('Delete'));
                }
            }
            $item['options'] = $options;

            if (in_array($item['published_status'], array_keys($itemstatus))) {
                $item['status'] = $itemstatus[$item['published_status']];
            } else {
                $item['status'] = $this->__('Unknown');
            }

            $item['infuture'] = DateUtil::getDatetimeDiff_AsField($item['from'], DateUtil::getDatetime(), 6) < 0;
            $newsitems[] = $item;
        }

        // Assign the items to the template
        $this->view->assign('newsitems', $newsitems);
        $this->view->assign('total_articles', $total_articles);

        // Assign the current status filter and the possible ones
        $this->view->assign('news_status', $news_status);
        $this->view->assign('itemstatus', $itemstatus);
        $this->view->assign('order', $order);

        $selectedcategories = array();
        if (is_array($filtercats)) {
            $catsarray = $filtercats['__CATEGORIES__'];
            foreach ($catsarray as $propname => $propid) {
                if ($propid > 0) {
                    $selectedcategories[$propname] = $propid; // removes categories set to 'all'
                }
            }
        }
        $this->view->assign('selectedcategories', $selectedcategories);

        // Return the output that has been generated by this function
        return $this->view->fetch('admin/view.tpl');
    }