]> git.agnieray.net Git - galette.git/blobdiff - galette/lib/Galette/Core/Mailing.php
Fix mailing preview; fixes #1800
[galette.git] / galette / lib / Galette / Core / Mailing.php
index 5b1013a90ea84a2253aae627d06b5b908adcf0b5..e2344014d58341e623a48eff892a3558d1337966 100644 (file)
@@ -7,7 +7,7 @@
  *
  * PHP version 5
  *
- * Copyright © 2009-2014 The Galette Team
+ * Copyright © 2009-2023 The Galette Team
  *
  * This file is part of Galette (http://galette.tuxfamily.org).
  *
@@ -28,7 +28,7 @@
  * @package   Galette
  *
  * @author    Johan Cwiklinski <johan@x-tnd.be>
- * @copyright 2009-2014 The Galette Team
+ * @copyright 2009-2023 The Galette Team
  * @license   http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
  * @link      http://galette.tuxfamily.org
  * @since     Available since 0.7dev - 2009-03-07
 namespace Galette\Core;
 
 use Analog\Analog;
+use ArrayObject;
 use Galette\Entity\Adherent;
 use Galette\IO\File;
+use Laminas\Db\ResultSet\ResultSet;
 
 /**
  * Mailing features
@@ -47,21 +49,39 @@ use Galette\IO\File;
  * @name      Mailing
  * @package   Galette
  * @author    Johan Cwiklinski <johan@x-tnd.be>
- * @copyright 2009-2014 The Galette Team
+ * @copyright 2009-2023 The Galette Team
  * @license   http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
  * @link      http://galette.tuxfamily.org
  * @since     Available since 0.7dev - 2009-03-07
+ *
+ * @property string $subject
+ * @property string $message
+ * @property boolean $html
+ * @property integer $current_step
+ * @property-read  integer $step
+ * @property integer|string $id
+ * @property-read string $alt_message
+ * @property-read string $wrapped_message
+ * @property-read PHPMailer\PHPMailer\PHPMailer $mail
+ * @property-read PHPMailer\PHPMailer\PHPMailer $_mail
+ * @property-read array $errors
+ * @property-read array $recipients
+ * @property-read string|false $tmp_path
+ * @property array $attachments
+ * @property-read string $sender_name
+ * @property-read string $sender_address
+ * @property integer $history_id
  */
 class Mailing extends GaletteMail
 {
-    const STEP_START = 0;
-    const STEP_PREVIEW = 1;
-    const STEP_SEND = 2;
-    const STEP_SENT = 3;
+    public const STEP_START = 0;
+    public const STEP_PREVIEW = 1;
+    public const STEP_SEND = 2;
+    public const STEP_SENT = 3;
 
-    const MIME_HTML = 'text/html';
-    const MIME_TEXT = 'text/plain';
-    const MIME_DEFAULT = self::MIME_TEXT;
+    public const MIME_HTML = 'text/html';
+    public const MIME_TEXT = 'text/plain';
+    public const MIME_DEFAULT = self::MIME_TEXT;
 
     private $id;
 
@@ -81,19 +101,16 @@ class Mailing extends GaletteMail
      * @param array       $members     An array of members
      * @param int         $id          Identifier, defaults to null
      */
-    public function __construct(Preferences $preferences, $members, $id = null)
+    public function __construct(Preferences $preferences, array $members = [], int $id = null)
     {
         parent::__construct($preferences);
-        if ($id !== null) {
-            $this->id = $id;
-        } else {
-            $this->generateNewId();
-        }
+        $this->id = $id ?? $this->generateNewId();
+
         $this->current_step = self::STEP_START;
         $this->mime_type = self::MIME_DEFAULT;
         /** TODO: add a preference that propose default mime-type to use,
             then init it here */
-        if ($members !== null) {
+        if (count($members)) {
             //Check which members have a valid email address and which have not
             $this->setRecipients($members);
         }
@@ -103,15 +120,23 @@ class Mailing extends GaletteMail
     /**
      * Generate new mailing id and temporary path
      *
-     * @return void
+     * @return string
      */
-    private function generateNewId()
+    private function generateNewId(): string
     {
-        global $zdb;
+        $id = '';
+        $chars = 'abcdefghjkmnpqrstuvwxyz0123456789';
+        $i = 0;
+        $size = 30;
+        while ($i <= $size - 1) {
+            $num = mt_rand(0, strlen($chars) - 1) % strlen($chars);
+            $id .= substr($chars, $num, 1);
+            $i++;
+        }
 
-        $pass = new Password($zdb);
-        $this->id = $pass->makeRandomPassword(30);
+        $this->id = $id;
         $this->generateTmpPath($this->id);
+        return $this->id;
     }
 
     /**
@@ -124,10 +149,7 @@ class Mailing extends GaletteMail
     private function generateTmpPath($id = null)
     {
         if ($id === null) {
-            global $zdb;
-
-            $pass = new Password($zdb);
-            $id = $pass->makeRandomPassword(30);
+            $id = $this->generateNewId();
         }
         $this->tmp_path = GALETTE_ATTACHMENTS_PATH . '/' . $id;
     }
@@ -160,17 +182,25 @@ class Mailing extends GaletteMail
     /**
      * Loads a mailing from history
      *
-     * @param ResultSet $rs  Mailing entry
-     * @param boolean   $new True if we create a 'new' mailing,
-     *                       false otherwise (from preview for example)
+     * @param ArrayObject $rs  Mailing entry
+     * @param boolean     $new True if we create a 'new' mailing,
+     *                         false otherwise (from preview for example)
      *
      * @return boolean
      */
-    public function loadFromHistory($rs, $new = true)
+    public function loadFromHistory(ArrayObject $rs, $new = true)
     {
         global $zdb;
 
-        $orig_recipients = unserialize($rs->mailing_recipients);
+        try {
+            $orig_recipients = unserialize($rs->mailing_recipients);
+        } catch (\Throwable $e) {
+            Analog::log(
+                'Unable to unserialize recipients for mailing ' . $rs->mailing_id,
+                Analog::ERROR
+            );
+            $orig_recipients = [];
+        }
 
         $_recipients = array();
         $mdeps = ['parent' => true];
@@ -181,6 +211,7 @@ class Mailing extends GaletteMail
         $this->setRecipients($_recipients);
         $this->subject = $rs->mailing_subject;
         $this->message = $rs->mailing_body;
+        $this->html = $this->message != strip_tags($this->message) ? true : false;
         if ($rs->mailing_sender_name !== null || $rs->mailing_sender_address !== null) {
             $this->setSender(
                 $rs->mailing_sender_name,
@@ -199,6 +230,7 @@ class Mailing extends GaletteMail
             }
             $this->history_id = $rs->mailing_id;
         }
+        return true;
     }
 
     /**
@@ -246,7 +278,7 @@ class Mailing extends GaletteMail
     /**
      * Apply final header to email and send it :-)
      *
-     * @return GaletteMail::MAIL_ERROR|GaletteMail::MAIL_SENT
+     * @return int
      */
     public function send()
     {
@@ -264,7 +296,7 @@ class Mailing extends GaletteMail
      *
      * @param array $members Array of Adherent objects
      *
-     * @return void
+     * @return bool
      */
     public function setRecipients($members)
     {
@@ -286,7 +318,7 @@ class Mailing extends GaletteMail
                 }
             }
         }
-        parent::setRecipients($m);
+        return parent::setRecipients($m);
     }
 
     /**
@@ -303,7 +335,7 @@ class Mailing extends GaletteMail
         }
 
         if (!file_exists($this->tmp_path)) {
-            //directory does not exists, create it
+            //directory does not exist, create it
             mkdir($this->tmp_path);
         }
 
@@ -330,7 +362,7 @@ class Mailing extends GaletteMail
      *
      * @param int $id Mailing history id
      *
-     * @return boolean
+     * @return void
      */
     public function moveAttachments($id)
     {
@@ -341,10 +373,10 @@ class Mailing extends GaletteMail
         ) {
             foreach ($this->attachments as &$attachment) {
                 $old_path = $attachment->getDestDir() . $attachment->getFileName();
-                $new_path = GALETTE_ATTACHMENTS_PATH . $this->id . '/' .
+                $new_path = GALETTE_ATTACHMENTS_PATH . $id . '/' .
                     $attachment->getFileName();
-                if (!file_exists(GALETTE_ATTACHMENTS_PATH . $this->id)) {
-                    mkdir(GALETTE_ATTACHMENTS_PATH . $this->id);
+                if (!file_exists(GALETTE_ATTACHMENTS_PATH . $id)) {
+                    mkdir(GALETTE_ATTACHMENTS_PATH . $id);
                 }
                 $moved = rename($old_path, $new_path);
                 if ($moved) {
@@ -416,7 +448,7 @@ class Mailing extends GaletteMail
      * @param boolean $temp Remove only tmporary attachments,
      *                      to avoid history breaking
      *
-     * @return void
+     * @return void|false
      */
     public function removeAttachments($temp = false)
     {
@@ -480,9 +512,9 @@ class Mailing extends GaletteMail
     /**
      * Global getter method
      *
-     * @param string $name name of the property we want to retrive
+     * @param string $name name of the property we want to retrieve
      *
-     * @return false|object the called property
+     * @return mixed the called property
      */
     public function __get($name)
     {
@@ -491,32 +523,23 @@ class Mailing extends GaletteMail
             switch ($name) {
                 case 'alt_message':
                     return $this->cleanedHtml();
-                    break;
                 case 'step':
                     return $this->current_step;
-                    break;
                 case 'subject':
                     return $this->getSubject();
-                    break;
                 case 'message':
                     return $this->getMessage();
-                    break;
                 case 'wrapped_message':
                     return $this->getWrappedMessage();
-                    break;
                 case 'html':
                     return $this->isHTML();
-                    break;
                 case 'mail':
                 case '_mail':
                     return $this->getPhpMailer();
-                    break;
                 case 'errors':
                     return $this->getErrors();
-                    break;
                 case 'recipients':
                     return $this->mrecipients;
-                    break;
                 case 'tmp_path':
                     if (isset($this->tmp_path) && trim($this->tmp_path) !== '') {
                         return $this->tmp_path;
@@ -524,23 +547,20 @@ class Mailing extends GaletteMail
                         //no attachments
                         return false;
                     }
-                    break;
                 case 'attachments':
                     return $this->attachments;
-                    break;
                 case 'sender_name':
                     return $this->getSenderName();
-                    break;
                 case 'sender_address':
                     return $this->getSenderAddress();
-                    break;
+                case 'history_id':
+                    return $this->$name;
                 default:
                     Analog::log(
                         '[' . get_class($this) . 'Trying to get ' . $name,
                         Analog::DEBUG
                     );
                     return $this->$name;
-                    break;
             }
         } else {
             Analog::log(
@@ -551,11 +571,46 @@ class Mailing extends GaletteMail
         }
     }
 
+    /**
+     * Global isset method
+     * Required for twig to access properties via __get
+     *
+     * @param string $name name of the property we want to retrieve
+     *
+     * @return bool
+     */
+    public function __isset($name)
+    {
+        $forbidden = array('ordered');
+        if (!in_array($name, $forbidden)) {
+            switch ($name) {
+                case 'alt_message':
+                case 'step':
+                case 'subject':
+                case 'message':
+                case 'wrapped_message':
+                case 'html':
+                case 'mail':
+                case '_mail':
+                case 'errors':
+                case 'recipients':
+                case 'tmp_path':
+                case 'attachments':
+                case 'sender_name':
+                case 'sender_address':
+                    return true;
+            }
+            return isset($this->$name);
+        }
+
+        return false;
+    }
+
     /**
      * Global setter method
      *
      * @param string $name  name of the property we want to assign a value to
-     * @param object $value a relevant value for the property
+     * @param mixed  $value a relevant value for the property
      *
      * @return void
      */
@@ -603,11 +658,9 @@ class Mailing extends GaletteMail
                 break;
             default:
                 Analog::log(
-                    '[' . get_class($this) . '] Unable to set proprety `' . $name . '`',
+                    '[' . get_class($this) . '] Unable to set property `' . $name . '`',
                     Analog::WARNING
                 );
-                return false;
-                break;
         }
     }
 }