[TikiWiki-commits] [Git][tikiwiki/tiki][master] [ENH] Prevent the same author from creating a newsletter with a name that already exists

Benoit Grégoire (@benoitg) via TikiWiki-cvs <[email protected]>
Newsgroups gmane.comp.cms.tiki.cvs
Message-ID <6914c6139efe1_2ce2fcc36063@gitlab-sidekiq-low-urgency-cpu-bound-v2-77d988696-t4kkg.mail>

Benoit Grégoire pushed to branch master at Tiki Wiki CMS Groupware / Tiki


Commits:
f6cd2132 by David Maene at 2025-11-12T17:30:27+00:00
[ENH] Prevent the same author from creating a newsletter with a name that already exists
---
* prevent the same author from creating a newsletter with a name that already exists

See merge request tikiwiki/tiki!8069

- - - - -


4 changed files:

- db/tiki.sql
- + installer/schema/20250815_newsletter_user_newsname_unique_constraint_tiki.sql
- lib/newsletters/nllib.php
- tiki-admin_newsletters.php


Changes:

=====================================
db/tiki.sql
=====================================
@@ -1910,6 +1910,7 @@ CREATE TABLE `tiki_newsletters` (
   `emptyClipBlocksSend` char(1) default 'n',
   PRIMARY KEY (`nlId`)
 ) ENGINE=MyISAM AUTO_INCREMENT=1 ;
+ALTER TABLE `tiki_newsletters` ADD CONSTRAINT `uniq_author_name` UNIQUE (author(100), name(100));
 
 DROP TABLE IF EXISTS `tiki_page_footnotes`;
 CREATE TABLE `tiki_page_footnotes` (


=====================================
installer/schema/20250815_newsletter_user_newsname_unique_constraint_tiki.sql
=====================================
@@ -0,0 +1,2 @@
+-- Ensure each author can only have one newsletter with a given name
+ALTER TABLE `tiki_newsletters` ADD CONSTRAINT `uniq_author_name` UNIQUE (author(100), name(100));


=====================================
lib/newsletters/nllib.php
=====================================
@@ -21,105 +21,147 @@ class NlLib extends TikiLib
     private const TABLE_NEWSLETTERS = 'tiki_newsletters';
     private const TABLE_SENT_NEWSLETTERS_FILES = 'tiki_sent_newsletters_files';
     private const TABLE_SENT_NEWSLETTERS = 'tiki_sent_newsletters';
-    public function replace_newsletter(
-        $nlId,
-        $name,
-        $description,
-        $allowUserSub,
-        $allowAnySub,
-        $unsubMsg,
-        $validateAddr,
-        $allowTxt,
-        $frequency,
-        $author,
-        $allowArticleClip = 'y',
-        $autoArticleClip = 'n',
-        $articleClipRange = null,
-        $articleClipTypes = '',
-        $emptyClipBlocksSend = 'n'
-    ) {
 
+    private function insertNewsletter(
+        string $name,
+        string $description,
+        string $allowUserSub = 'y',
+        string $allowAnySub = 'n',
+        string $unsubMsg = '',
+        string $validateAddr = 'n',
+        string $allowTxt = 'n',
+        string $frequency = '',
+        string $author = '',
+        string $allowArticleClip = 'y',
+        string $autoArticleClip = 'n',
+        ?string $articleClipRange = null,
+        string $articleClipTypes = '',
+        string $emptyClipBlocksSend = 'n'
+    ): int|false {
+        $query = 'insert into `' . self::TABLE_NEWSLETTERS . '` (
+                    `name`, `description`, `created`, `lastSent`, `editions`, `users`,
+                    `allowUserSub`, `allowTxt`, `allowAnySub`, `unsubMsg`, `validateAddr`,
+                    `frequency`, `author`, `allowArticleClip`, `autoArticleClip`,
+                    `articleClipRange`, `articleClipTypes`, `emptyClipBlocksSend`
+                ) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)';
+
+        $result = $this->query($query, [
+            $name,
+            $description,
+            (int) $this->now,
+            0,
+            0,
+            0,
+            $allowUserSub,
+            $allowTxt,
+            $allowAnySub,
+            $unsubMsg,
+            $validateAddr,
+            $frequency,
+            $author,
+            $allowArticleClip,
+            $autoArticleClip,
+            $articleClipRange,
+            $articleClipTypes,
+            $emptyClipBlocksSend,
+        ]);
+
+        if ($result) {
+            return $this->getOne('select max(`nlId`) from `' . self::TABLE_NEWSLETTERS . '` where `created`=?', [(int) $this->now]);
+        }
+
+        return false;
+    }
+
+    private function updateNewsletter(
+        int $nlId,
+        string $name,
+        string $description,
+        string $allowUserSub,
+        string $allowAnySub,
+        string $unsubMsg,
+        string $validateAddr,
+        string $allowTxt,
+        string $frequency,
+        string $allowArticleClip,
+        string $autoArticleClip,
+        ?string $articleClipRange,
+        string $articleClipTypes,
+        string $emptyClipBlocksSend
+    ): int|false {
+        $query = 'update `' . self::TABLE_NEWSLETTERS . '` set  
+                `name`=?,
+                `description`=?,
+                `allowUserSub`=?,
+                `allowTxt`=?,
+                `allowAnySub`=?,
+                `unsubMsg`=?,
+                `validateAddr`=?,
+                `frequency`=?,
+                `allowArticleClip`=?,
+                `autoArticleClip`=?,
+                `articleClipRange`=?,
+                `articleClipTypes`=?,
+                `emptyClipBlocksSend`=? 
+                where `nlId`=?';
+        $result = $this->query($query, [
+            $name,
+            $description,
+            $allowUserSub,
+            $allowTxt,
+            $allowAnySub,
+            $unsubMsg,
+            $validateAddr,
+            $frequency,
+            $allowArticleClip,
+            $autoArticleClip,
+            $articleClipRange,
+            $articleClipTypes,
+            $emptyClipBlocksSend,
+            (int) $nlId,
+        ]);
+
+        if (! $result && ! $result->numRows()) {
+            return false;
+        }
+
+        return $nlId;
+    }
+
+    public function replace_newsletter(
+        ?int $nlId,
+        string $name,
+        string $description,
+        string $allowUserSub,
+        string $allowAnySub,
+        string $unsubMsg,
+        string $validateAddr,
+        string $allowTxt,
+        string $frequency,
+        string $author,
+        string $allowArticleClip = 'y',
+        string $autoArticleClip = 'n',
+        ?string $articleClipRange = null,
+        string $articleClipTypes = '',
+        string $emptyClipBlocksSend = 'n'
+    ): int|false {
         if ($nlId) {
-            $query = "update `" . self::TABLE_NEWSLETTERS . "` set `name`=?,
-                                `description`=?,
-                                `allowUserSub`=?,
-                                `allowTxt`=?,
-                                `allowAnySub`=?,
-                                `unsubMsg`=?,
-                                `validateAddr`=?,
-                                `frequency`=?,
-                                `allowArticleClip`=?,
-                                `autoArticleClip`=?,
-                                `articleClipRange`=?,
-                                `articleClipTypes`=?,
-                                `emptyClipBlocksSend`=?
-                                where `nlId`=?";
-            $result = $this->query(
-                $query,
-                [
-                        $name,
-                        $description,
-                        $allowUserSub,
-                        $allowTxt,
-                        $allowAnySub,
-                        $unsubMsg,
-                        $validateAddr,
-                        $frequency,
-                        $allowArticleClip,
-                        $autoArticleClip,
-                        $articleClipRange,
-                        $articleClipTypes,
-                        $emptyClipBlocksSend,
-                        (int) $nlId,
-                ]
-            );
+            return $this->updateNewsletter($nlId, $name, $description, $allowUserSub, $allowAnySub, $unsubMsg, $validateAddr, $allowTxt, $frequency, $allowArticleClip, $autoArticleClip, $articleClipRange, $articleClipTypes, $emptyClipBlocksSend);
         } else {
-            $query = "insert into `" . self::TABLE_NEWSLETTERS . "`(
-                                `name`,
-                                `description`,
-                                `created`,
-                                `lastSent`,
-                                `editions`,
-                                `users`,
-                                `allowUserSub`,
-                                `allowTxt`,
-                                `allowAnySub`,
-                                `unsubMsg`,
-                                `validateAddr`,
-                                `frequency`,
-                                `author`,
-                                `allowArticleClip`,
-                                `autoArticleClip`,
-                                `articleClipRange`,
-                                `articleClipTypes`
-                                ) ";
-            $query .= " values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
-            $result = $this->query(
-                $query,
-                [
-                    $name,
-                    $description,
-                    $this->now,
-                    0,
-                    0,
-                    0,
-                    $allowUserSub,
-                    $allowTxt,
-                    $allowAnySub,
-                    $unsubMsg,
-                    $validateAddr,
-                    null,
-                    $author,
-                    $allowArticleClip,
-                    $autoArticleClip,
-                    $articleClipRange,
-                    $articleClipTypes,
-                ]
-            );
-            $queryid = "select max(`nlId`) from `" . self::TABLE_NEWSLETTERS . "` where `created`=?";
-            $nlId = $this->getOne($queryid, [(int) $this->now]);
+            if (! $this->isNewsletterUnique($name, $author)) {
+                return -1;
+            } else {
+                return $this->insertNewsletter($name, $description, $allowUserSub, $allowAnySub, $unsubMsg, $validateAddr, $allowTxt, $frequency, $author, $allowArticleClip, $autoArticleClip, $articleClipRange, $articleClipTypes, $emptyClipBlocksSend);
+            }
         }
-        return $nlId;
+    }
+
+    private function isNewsletterUnique(string $name, string $author): bool
+    {
+        $query = 'select `nlId` from `' . self::TABLE_NEWSLETTERS . '` where `name` = ? and `author` = ?';
+        $item = $this->getOne($query, [$name, $author]);
+
+        return ! $item;
     }
 
     public function replace_edition($nlId, $subject, $data, $users, $editionId = 0, $draft = false, $datatxt = '', $files = [], $wysiwyg = null, $is_html = null)


=====================================
tiki-admin_newsletters.php
=====================================
@@ -55,8 +55,7 @@ $smarty->assign('nlId', $_REQUEST["nlId"]);
 $perms = Perms::get(['type' => 'newsletter', 'object' => $_REQUEST['nlId']]);
 
 if ($perms->admin_newsletters != 'y') {
-    Feedback::errorPage(['mes' => tr('You do not have the permission that is needed to use this feature'),
-                         'errortype' => 401]);
+    Feedback::errorPage(['mes' => tr('You do not have the permission that is needed to use this feature'), 'errortype' => 401]);
 }
 $defaultArticleClipRange = 3600 * 24; // one day
 if ($_REQUEST["nlId"]) {
@@ -152,7 +151,7 @@ if (isset($_REQUEST["save"]) && $access->checkCsrf()) {
         if (! isset($_REQUEST['frequency'])) {
             $_REQUEST['frequency'] = 0;
         }
-        $sid = $nllib->replace_newsletter(
+        $result = $nllib->replace_newsletter(
             $_REQUEST["nlId"],
             $_REQUEST["name"],
             $_REQUEST["description"],
@@ -169,11 +168,18 @@ if (isset($_REQUEST["save"]) && $access->checkCsrf()) {
             $articleClipTypes,
             $_REQUEST["emptyClipBlocksSend"]
         );
-
-        if ($sid) {
-            Feedback::success(tr('Newsletter created or modified'));
-        } else {
-            Feedback::error(tr('Newsletter not created or modified'));
+        // Handle the result of the operation
+        // -1 indicates that the newsletter already exists
+        // If the result is an integer > 0, it indicates the ID of the updated newsletter
+        // If the result is an array, it indicates a new newsletter was created
+        if ($result === false) {
+            Feedback::error(tr('A newsletter error occurred during the information-writing process.'));
+        } elseif ($result === -1) {
+            Feedback::error(tr('Newsletter already exists. with the same name'));
+        } elseif (is_int($result) && $result > 0) {
+            Feedback::success(tr('Newsletter updated successfully'));
+        } elseif (is_array($result)) {
+            Feedback::success(tr('Newsletter created successfully'));
         }
     }
 



View it on GitLab: https://gitlab.com/tikiwiki/tiki/-/commit/f6cd213282542e1d2e165280b5b0f2e10374178b

-- 
View it on GitLab: https://gitlab.com/tikiwiki/tiki/-/commit/f6cd213282542e1d2e165280b5b0f2e10374178b
You're receiving this email because of your account on gitlab.com.

_______________________________________________
TikiWiki-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/tikiwiki-cvs
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.