+ $this->nl = new NewsLetter($issue['nlid']);
+ }
+ $this->id = $id;
+ $this->shortname = $issue['short_name'];
+ $this->date = $issue['date'];
+ $this->send_before = $issue['send_before'];
+ $this->state = $issue['state'];
+ $this->title = $issue['title'];
+ $this->title_mail = $issue['mail_title'];
+ $this->head = $issue['head'];
+ $this->signature = $issue['signature'];
+ $this->sufb = $this->importJSonStoredUFB($issue['sufb_json']);
+
+ if ($fetch_articles) {
+ $this->fetchArticles();
+ }
+ }
+
+ protected function fetchArticles($force = false)
+ {
+ if (count($this->arts) && !$force) {
+ return;
+ }
+
+ // Load the articles
+ $res = XDB::iterRow(
+ 'SELECT a.title, a.body, a.append, a.aid, a.cid, a.pos
+ FROM newsletter_art AS a
+ INNER JOIN newsletter_issues AS ni USING(id)
+ LEFT JOIN newsletter_cat AS c ON (a.cid = c.cid)
+ WHERE a.id = {?}
+ ORDER BY c.pos, a.pos',
+ $this->id);
+ while (list($title, $body, $append, $aid, $cid, $pos) = $res->next()) {
+ $this->arts[$cid][$aid] = new NLArticle($title, $body, $append, $aid, $cid, $pos);
+ }
+ }
+
+ protected function importJSonStoredUFB($json = null)
+ {
+ require_once 'ufbuilder.inc.php';
+ $ufb = $this->nl->getSubscribersUFB();
+ if (is_null($json)) {
+ return new StoredUserFilterBuilder($ufb, new PFC_True());
+ }
+ $export = json_decode($json, true);
+ if (is_null($export)) {
+ PlErrorReport::report("Invalid json while reading NL {$this->nlid}, issue {$this->id}: failed to import '''{$json}'''.");
+ return new StoredUserFilterBuilder($ufb, new PFC_True());
+ }
+ $sufb = new StoredUserFilterBuilder($ufb);
+ $sufb->fillFromExport($export);
+ return $sufb;
+ }
+
+ protected function exportStoredUFBAsJSon()
+ {
+ return json_encode($this->sufb->export());
+ }
+
+ public function id()
+ {
+ return is_null($this->shortname) ? $this->id : $this->shortname;
+ }
+
+ protected function selectId($where)
+ {
+ $res = XDB::query("SELECT IFNULL(ni.short_name, ni.id)
+ FROM newsletter_issues AS ni
+ WHERE ni.state != 'new' AND ni.nlid = {?} AND ${where}
+ LIMIT 1", $this->nl->id);
+ if ($res->numRows() != 1) {
+ return null;
+ }
+ return $res->fetchOneCell();
+ }
+
+ /** Delete this issue
+ * @return True if the issue could be deleted, false otherwise.
+ * Related articles will be deleted through cascading FKs.
+ * If this issue was the last issue for at least one subscriber, the deletion will be aborted.
+ */
+ public function delete()
+ {
+ if ($this->state == self::STATE_NEW) {
+ $res = XDB::query('SELECT COUNT(*)
+ FROM newsletter_ins
+ WHERE last = {?}', $this->id);
+ if ($res->fetchOneCell() > 0) {
+ return false;
+ }
+
+ return XDB::execute('DELETE FROM newsletter_issues
+ WHERE id = {?}', $this->id);
+ } else {
+ return false;
+ }
+ }
+
+ /** Schedule a mailing of this NL
+ * If the 'send_before' field was NULL, it is set to the current time.
+ * @return Boolean Whether the date could be set (false if trying to schedule an already sent NL)
+ */
+ public function scheduleMailing()
+ {
+ if ($this->state == self::STATE_NEW) {
+ $success = XDB::execute('UPDATE newsletter_issues
+ SET state = \'pending\', send_before = IFNULL(send_before, NOW())
+ WHERE id = {?}',
+ $this->id);
+ if ($success) {
+ global $globals;
+ $mailer = new PlMailer('newsletter/notify_scheduled.mail.tpl');
+ $mailer->assign('issue', $this);
+ $mailer->assign('base', $globals->baseurl);
+ $mailer->send();
+ $this->refresh();