Add permission to manage own articles
[GitHub/WoltLab/WCF.git] / wcfsetup / install / files / lib / data / article / ArticleAction.class.php
index 3fc74565735aacd1271183a73b5f9cf815fe8aa8..bd76ed3fef5207734529c7489ca7e6acc25f53d4 100644 (file)
@@ -1,5 +1,4 @@
 <?php
-declare(strict_types=1);
 namespace wcf\data\article;
 use wcf\data\article\category\ArticleCategory;
 use wcf\data\article\content\ArticleContent;
@@ -9,6 +8,7 @@ use wcf\data\language\Language;
 use wcf\data\AbstractDatabaseObjectAction;
 use wcf\system\clipboard\ClipboardHandler;
 use wcf\system\comment\CommentHandler;
+use wcf\system\exception\PermissionDeniedException;
 use wcf\system\exception\UserInputException;
 use wcf\system\language\LanguageFactory;
 use wcf\system\like\LikeHandler;
@@ -138,6 +138,10 @@ class ArticleAction extends AbstractDatabaseObjectAction {
                        UserStorageHandler::getInstance()->resetAll('unreadArticles');
                }
                
+               if ($article->publicationStatus == Article::PUBLISHED) {
+                       ArticleEditor::updateArticleCounter([$article->userID => 1]);
+               }
+               
                return $article;
        }
        
@@ -241,6 +245,28 @@ class ArticleAction extends AbstractDatabaseObjectAction {
                if (ARTICLE_ENABLE_VISIT_TRACKING) {
                        UserStorageHandler::getInstance()->resetAll('unreadArticles');
                }
+               
+               $publicationStatus = (isset($this->parameters['data']['publicationStatus'])) ? $this->parameters['data']['publicationStatus'] : null;
+               if ($publicationStatus !== null) {
+                       $usersToArticles = [];
+                       /** @var ArticleEditor $articleEditor */
+                       foreach ($this->objects as $articleEditor) {
+                               if ($publicationStatus != $articleEditor->publicationStatus) {
+                                       // The article was published before or was now published.
+                                       if ($publicationStatus == Article::PUBLISHED || $articleEditor->publicationStatus == Article::PUBLISHED) {
+                                               if (!isset($usersToArticles[$articleEditor->userID])) {
+                                                       $usersToArticles[$articleEditor->userID] = 0;
+                                               }
+                                               
+                                               $usersToArticles[$articleEditor->userID] += ($publicationStatus == Article::PUBLISHED) ? 1 : -1;
+                                       }
+                               }
+                       }
+                       
+                       if (!empty($usersToArticles)) {
+                               ArticleEditor::updateArticleCounter($usersToArticles);
+                       }
+               }
        }
        
        /**
@@ -249,8 +275,6 @@ class ArticleAction extends AbstractDatabaseObjectAction {
         * @throws      UserInputException
         */
        public function validateDelete() {
-               WCF::getSession()->checkPermissions(['admin.content.article.canManageArticle']);
-               
                if (empty($this->objects)) {
                        $this->readObjects();
                        
@@ -260,6 +284,10 @@ class ArticleAction extends AbstractDatabaseObjectAction {
                }
                
                foreach ($this->getObjects() as $article) {
+                       if (!$article->canDelete()) {
+                               throw new PermissionDeniedException();
+                       }
+                       
                        if (!$article->isDeleted) {
                                throw new UserInputException('objectIDs');
                        }
@@ -306,8 +334,6 @@ class ArticleAction extends AbstractDatabaseObjectAction {
         * @throws      UserInputException
         */
        public function validateTrash() {
-               WCF::getSession()->checkPermissions(['admin.content.article.canManageArticle']);
-               
                if (empty($this->objects)) {
                        $this->readObjects();
                        
@@ -317,6 +343,10 @@ class ArticleAction extends AbstractDatabaseObjectAction {
                }
                
                foreach ($this->getObjects() as $article) {
+                       if (!$article->canDelete()) {
+                               throw new PermissionDeniedException();
+                       }
+                       
                        if ($article->isDeleted) {
                                throw new UserInputException('objectIDs');
                        }
@@ -531,8 +561,6 @@ class ArticleAction extends AbstractDatabaseObjectAction {
         * @throws      UserInputException
         */
        public function validatePublish() {
-               WCF::getSession()->checkPermissions(['admin.content.article.canManageArticle']);
-               
                if (empty($this->objects)) {
                        $this->readObjects();
                        
@@ -542,6 +570,10 @@ class ArticleAction extends AbstractDatabaseObjectAction {
                }
                
                foreach ($this->getObjects() as $article) {
+                       if (!$article->canPublish()) {
+                               throw new PermissionDeniedException();  
+                       }
+                       
                        if ($article->publicationStatus == Article::PUBLISHED) {
                                throw new UserInputException('objectIDs');
                        }
@@ -552,14 +584,23 @@ class ArticleAction extends AbstractDatabaseObjectAction {
         * Publishes articles.
         */
        public function publish() {
+               $usersToArticles = [];
                foreach ($this->getObjects() as $articleEditor) {
                        $articleEditor->update([
                                'time' => TIME_NOW,
                                'publicationStatus' => Article::PUBLISHED,
                                'publicationDate' => 0
                        ]);
+                       
+                       if (!isset($usersToArticles[$articleEditor->userID])) {
+                               $usersToArticles[$articleEditor->userID] = 0;
+                       }
+                       
+                       $usersToArticles[$articleEditor->userID]++;
                }
                
+               ArticleEditor::updateArticleCounter($usersToArticles);
+               
                $this->unmarkItems();
        }
        
@@ -569,8 +610,6 @@ class ArticleAction extends AbstractDatabaseObjectAction {
         * @throws      UserInputException
         */
        public function validateUnpublish() {
-               WCF::getSession()->checkPermissions(['admin.content.article.canManageArticle']);
-               
                if (empty($this->objects)) {
                        $this->readObjects();
                        
@@ -580,6 +619,10 @@ class ArticleAction extends AbstractDatabaseObjectAction {
                }
                
                foreach ($this->getObjects() as $article) {
+                       if (!$article->canPublish()) {
+                               throw new PermissionDeniedException();
+                       }
+                       
                        if ($article->publicationStatus != Article::PUBLISHED) {
                                throw new UserInputException('objectIDs');
                        }
@@ -590,10 +633,19 @@ class ArticleAction extends AbstractDatabaseObjectAction {
         * Unpublishes articles.
         */
        public function unpublish() {
+               $usersToArticles = [];
                foreach ($this->getObjects() as $articleEditor) {
                        $articleEditor->update(['publicationStatus' => Article::UNPUBLISHED]);
+                       
+                       if (!isset($usersToArticles[$articleEditor->userID])) {
+                               $usersToArticles[$articleEditor->userID] = 0;
+                       }
+                       
+                       $usersToArticles[$articleEditor->userID]--;
                }
                
+               ArticleEditor::updateArticleCounter($usersToArticles);
+               
                $this->unmarkItems();
        }