Added contributor role for articles
authorMarcel Werk <burntime@woltlab.com>
Fri, 9 Sep 2016 10:01:22 +0000 (12:01 +0200)
committerMarcel Werk <burntime@woltlab.com>
Fri, 9 Sep 2016 10:01:28 +0000 (12:01 +0200)
com.woltlab.wcf/acpMenu.xml
com.woltlab.wcf/userGroupOption.xml
wcfsetup/install/files/acp/templates/articleAdd.tpl
wcfsetup/install/files/lib/acp/form/ArticleAddForm.class.php
wcfsetup/install/files/lib/acp/form/ArticleEditForm.class.php
wcfsetup/install/files/lib/acp/page/ArticleListPage.class.php
wcfsetup/install/files/lib/data/article/Article.class.php
wcfsetup/install/lang/de.xml
wcfsetup/install/lang/en.xml

index 1dee560d6c395aedf6c7b9e837a4cd9d5175fb26..a951c64058ee2464ddfd3fd57bc0367032be6081 100644 (file)
                        <acpmenuitem name="wcf.acp.menu.link.article.list">
                                <controller>wcf\acp\page\ArticleListPage</controller>
                                <parent>wcf.acp.menu.link.article</parent>
-                               <permissions>admin.content.article.canManageArticle</permissions>
+                               <permissions>admin.content.article.canManageArticle,admin.content.article.canContributeArticle</permissions>
                        </acpmenuitem>
                        <acpmenuitem name="wcf.acp.menu.link.article.add">
                                <controller>wcf\acp\form\ArticleAddForm</controller>
                                <parent>wcf.acp.menu.link.article.list</parent>
-                               <permissions>admin.content.article.canManageArticle</permissions>
+                               <permissions>admin.content.article.canManageArticle,admin.content.article.canContributeArticle</permissions>
                                <icon>fa-plus</icon>
                        </acpmenuitem>
                
index f17999967ff98c3020cad25897769b63bdee0827..7c3ed150dd3b5bfccb4c6b4ac8f2c8814b926bc2 100644 (file)
                                <admindefaultvalue>1</admindefaultvalue>
                                <usersonly>1</usersonly>
                        </option>
+                       <option name="admin.content.article.canContributeArticle">
+                               <categoryname>admin.content</categoryname>
+                               <optiontype>boolean</optiontype>
+                               <defaultvalue>0</defaultvalue>
+                               <admindefaultvalue>1</admindefaultvalue>
+                               <usersonly>1</usersonly>
+                       </option>
                        <option name="admin.content.article.canManageCategory">
                                <categoryname>admin.content</categoryname>
                                <optiontype>boolean</optiontype>
index 8408efbb0350e160f542b0aebfebb35d10fddbb5..4f3989bbd54a257be109cb7dd6deb1bc741bd48b 100644 (file)
@@ -1,20 +1,22 @@
 {include file='header' pageTitle='wcf.acp.article.'|concat:$action}
 
-<script data-relocate="true">
-       $(function() {
-               $('input[type="radio"][name="publicationStatus"]').change(function(event) {
-                       var $selected = $('input[type="radio"][name="publicationStatus"]:checked');
-                       if ($selected.length > 0) {
-                               if ($selected.val() == 2) {
-                                       $('#publicationDateDl').show();
-                               }
-                               else {
-                                       $('#publicationDateDl').hide();
+{if $__wcf->session->getPermission('admin.content.article.canManageArticle')}
+       <script data-relocate="true">
+               $(function() {
+                       $('input[type="radio"][name="publicationStatus"]').change(function(event) {
+                               var $selected = $('input[type="radio"][name="publicationStatus"]:checked');
+                               if ($selected.length > 0) {
+                                       if ($selected.val() == 2) {
+                                               $('#publicationDateDl').show();
+                                       }
+                                       else {
+                                               $('#publicationDateDl').hide();
+                                       }
                                }
-                       }
-               }).trigger('change');
-       });
-</script>
+                       }).trigger('change');
+               });
+       </script>
+{/if}
 
 <script data-relocate="true">
        require(['WoltLabSuite/Core/Ui/User/Search/Input'], function(UiUserSearchInput) {
                        </dd>
                </dl>
                
-               <dl>
-                       <dt><label for="categoryID">{lang}wcf.acp.article.publicationStatus{/lang}</label></dt>
-                       <dd class="floated">
-                               <label><input type="radio" name="publicationStatus" value="0"{if $publicationStatus == 0} checked{/if}> {lang}wcf.acp.article.publicationStatus.unpublished{/lang}</label>
-                               <label><input type="radio" name="publicationStatus" value="1"{if $publicationStatus == 1} checked{/if}> {lang}wcf.acp.article.publicationStatus.published{/lang}</label>
-                               <label><input type="radio" name="publicationStatus" value="2"{if $publicationStatus == 2} checked{/if}> {lang}wcf.acp.article.publicationStatus.delayed{/lang}</label>
-                       </dd>
-               </dl>
-               
-               <dl id="publicationDateDl"{if $errorField == 'publicationDate'} class="formError"{/if}{if $publicationStatus != 2} style="display: none"{/if}>
-                       <dt><label for="publicationDate">{lang}wcf.acp.article.publicationDate{/lang}</label></dt>
-                       <dd>
-                               <input type="datetime" id="publicationDate" name="publicationDate" value="{$publicationDate}" class="medium">
-                               {if $errorField == 'publicationDate'}
-                                       <small class="innerError">
-                                               {if $errorType == 'empty'}
-                                                       {lang}wcf.global.form.error.empty{/lang}
-                                               {else}
-                                                       {lang}wcf.acp.article.publicationDate.error.{@$errorType}{/lang}
-                                               {/if}
-                                       </small>
-                               {/if}
-                       </dd>
-               </dl>
+               {if $__wcf->session->getPermission('admin.content.article.canManageArticle')}
+                       <dl>
+                               <dt><label for="categoryID">{lang}wcf.acp.article.publicationStatus{/lang}</label></dt>
+                               <dd class="floated">
+                                       <label><input type="radio" name="publicationStatus" value="0"{if $publicationStatus == 0} checked{/if}> {lang}wcf.acp.article.publicationStatus.unpublished{/lang}</label>
+                                       <label><input type="radio" name="publicationStatus" value="1"{if $publicationStatus == 1} checked{/if}> {lang}wcf.acp.article.publicationStatus.published{/lang}</label>
+                                       <label><input type="radio" name="publicationStatus" value="2"{if $publicationStatus == 2} checked{/if}> {lang}wcf.acp.article.publicationStatus.delayed{/lang}</label>
+                               </dd>
+                       </dl>
+                       
+                       <dl id="publicationDateDl"{if $errorField == 'publicationDate'} class="formError"{/if}{if $publicationStatus != 2} style="display: none"{/if}>
+                               <dt><label for="publicationDate">{lang}wcf.acp.article.publicationDate{/lang}</label></dt>
+                               <dd>
+                                       <input type="datetime" id="publicationDate" name="publicationDate" value="{$publicationDate}" class="medium">
+                                       {if $errorField == 'publicationDate'}
+                                               <small class="innerError">
+                                                       {if $errorType == 'empty'}
+                                                               {lang}wcf.global.form.error.empty{/lang}
+                                                       {else}
+                                                               {lang}wcf.acp.article.publicationDate.error.{@$errorType}{/lang}
+                                                       {/if}
+                                               </small>
+                                       {/if}
+                               </dd>
+                       </dl>
+               {/if}
                
                <dl>
                        <dt></dt>
index b99ee458f577260c256c7e79734ba2dac7ebbaa4..b3eaeaf691c40347dbb34369d4f36f5edff8c2c2 100644 (file)
@@ -42,7 +42,7 @@ class ArticleAddForm extends AbstractForm {
        /**
         * @inheritDoc
         */
-       public $neededPermissions = ['admin.content.article.canManageArticle'];
+       public $neededPermissions = ['admin.content.article.canManageArticle', 'admin.content.article.canContributeArticle'];
        
        /**
         * true if created article is multi-lingual
@@ -193,7 +193,14 @@ class ArticleAddForm extends AbstractForm {
                        $this->timeObj = \DateTime::createFromFormat('Y-m-d\TH:i:sP', $this->time);
                }
                if (!empty($_POST['enableComments'])) $this->enableComments = 1;
-               if (isset($_POST['publicationStatus'])) $this->publicationStatus = intval($_POST['publicationStatus']);
+               
+               if (WCF::getSession()->getPermission('admin.content.article.canManageArticle')) {
+                       if (isset($_POST['publicationStatus'])) $this->publicationStatus = intval($_POST['publicationStatus']);
+               }
+               else {
+                       $this->publicationStatus = Article::UNPUBLISHED;
+               }
+               
                if ($this->publicationStatus == Article::DELAYED_PUBLICATION && isset($_POST['publicationDate'])) {
                        $this->publicationDate = $_POST['publicationDate'];
                        $this->publicationDateObj = \DateTime::createFromFormat('Y-m-d\TH:i:sP', $this->publicationDate);
@@ -383,6 +390,10 @@ class ArticleAddForm extends AbstractForm {
                $dateTime = DateUtil::getDateTimeByTimestamp(TIME_NOW);
                $dateTime->setTimezone(WCF::getUser()->getTimeZone());
                $this->time = $dateTime->format('c');
+               
+               if (!WCF::getSession()->getPermission('admin.content.article.canManageArticle')) {
+                       $this->publicationStatus = Article::UNPUBLISHED;
+               }
        }
        
        /**
index 310d28e4e64cb5508b1eaea9d11ccdbc75000ee9..6890b0131d212e00806e901140ea3bf97cc17f2e 100644 (file)
@@ -4,6 +4,7 @@ use wcf\data\article\Article;
 use wcf\data\article\ArticleAction;
 use wcf\form\AbstractForm;
 use wcf\system\exception\IllegalLinkException;
+use wcf\system\exception\PermissionDeniedException;
 use wcf\system\language\LanguageFactory;
 use wcf\system\tagging\TagEngine;
 use wcf\system\WCF;
@@ -48,6 +49,12 @@ class ArticleEditForm extends ArticleAddForm {
                        throw new IllegalLinkException();
                }
                if ($this->article->isMultilingual) $this->isMultilingual = 1;
+               
+               if (!WCF::getSession()->getPermission('admin.content.article.canManageArticle')) {
+                       if ($this->article->userID != WCF::getUser()->userID || $this->article->publicationStatus != Article::UNPUBLISHED) {
+                               throw new PermissionDeniedException();
+                       }
+               }
        }
        
        /**
index e5f1dc51b6661cd18ee495e44d61e7d3793a7f57..10293de9b473b33ceb0dcd35ad811ce20bfc8beb 100644 (file)
@@ -1,5 +1,6 @@
 <?php
 namespace wcf\acp\page;
+use wcf\data\article\Article;
 use wcf\data\article\ArticleList;
 use wcf\data\article\ViewableArticleList;
 use wcf\data\category\CategoryNodeTree;
@@ -38,7 +39,7 @@ class ArticleListPage extends SortablePage {
        /**
         * @inheritDoc
         */
-       public $neededPermissions = ['admin.content.article.canManageArticle'];
+       public $neededPermissions = ['admin.content.article.canManageArticle', 'admin.content.article.canContributeArticle'];
        
        /**
         * @inheritDoc
@@ -123,6 +124,11 @@ class ArticleListPage extends SortablePage {
                if (!empty($this->content)) {
                        $this->objectList->getConditionBuilder()->add('article.articleID IN (SELECT articleID FROM wcf'.WCF_N.'_article_content WHERE content LIKE ?)', ['%'.$this->content.'%']);
                }
+               if (!WCF::getSession()->getPermission('admin.content.article.canManageArticle')) {
+                       // only show own articles
+                       $this->objectList->getConditionBuilder()->add('article.userID = ?', [WCF::getUser()->userID]);
+                       $this->objectList->getConditionBuilder()->add('article.publicationStatus = ?', [Article::UNPUBLISHED]);
+               }
                
                $this->objectList->sqlSelects = "(SELECT title FROM wcf".WCF_N."_article_content WHERE articleID = article.articleID AND (languageID IS NULL OR languageID = ".WCF::getLanguage()->languageID.") LIMIT 1) AS title";
        }
index 7ef36e91a50ac07db1f665a4b2e0d4119ea62f12..baca875de67b3a180ffe420e7c6be4e90a52411d 100644 (file)
@@ -81,6 +81,12 @@ class Article extends DatabaseObject implements ILinkableObject {
         * @return      boolean
         */
        public function canRead() {
+               if ($this->publicationStatus != Article::PUBLISHED) {
+                       if (!WCF::getSession()->getPermission('admin.content.article.canManageArticle') && (!WCF::getSession()->getPermission('admin.content.article.canContributeArticle') || $this->userID != WCF::getUser()->userID)) {
+                               return false;
+                       }
+               }
+               
                if ($this->getCategory()) {
                        return $this->getCategory()->isAccessible();
                }
index f81fb049ca741fc23b5eee7d9f947766588c48ca..205bb5ab143400a522aeabf83760f0797b166166 100644 (file)
                <item name="wcf.acp.group.option.user.tag.canViewTag"><![CDATA[Kann Tag sehen]]></item>
                <item name="wcf.acp.group.option.category.user.cms"><![CDATA[CMS]]></item>
                <item name="wcf.acp.group.option.admin.content.article.canManageArticle"><![CDATA[Kann Artikel verwalten]]></item>
+               <item name="wcf.acp.group.option.admin.content.article.canContributeArticle"><![CDATA[Kann Artikel einreichen]]></item>
                <item name="wcf.acp.group.option.admin.content.article.canManageCategory"><![CDATA[Kann Artikel-Kategorien verwalten]]></item>
                <item name="wcf.acp.group.option.admin.content.cms.canManageBox"><![CDATA[Kann Boxen verwalten]]></item>
                <item name="wcf.acp.group.option.admin.content.cms.canManageMedia"><![CDATA[Kann Medien verwalten]]></item>
index 1d38c56fadc5452b32bb128f41289df3d0c001de..6f1ff9c69cd927bf72420581b8298442dec2122f 100644 (file)
@@ -512,6 +512,7 @@ Examples for medium ID detection:
                <item name="wcf.acp.group.option.user.tag.canViewTag"><![CDATA[Can view tags]]></item>
                <item name="wcf.acp.group.option.category.user.cms"><![CDATA[CMS]]></item>
                <item name="wcf.acp.group.option.admin.content.article.canManageArticle"><![CDATA[Can manage articles]]></item>
+               <item name="wcf.acp.group.option.admin.content.article.canContributeArticle"><![CDATA[Can contribute articles]]></item>
                <item name="wcf.acp.group.option.admin.content.article.canManageCategory"><![CDATA[Can manage article categories]]></item>
                <item name="wcf.acp.group.option.admin.content.cms.canManageBox"><![CDATA[Can manage boxes]]></item>
                <item name="wcf.acp.group.option.admin.content.cms.canManageMedia"><![CDATA[Can manage media]]></item>