X-Git-Url: http://git.polytechnique.org/?a=blobdiff_plain;f=include%2Fnewsletter.inc.php;h=623121f97d4ddbe9f8f5d01f75e77109dfa8bdbe;hb=d3a4f32c262cefe7741fb03e5201e3b49fba95d1;hp=da97493d4a03fa379c359a3e6026a076de764680;hpb=8dc39e6a39d364ac62ea9a303a38e33a69865033;p=platal.git diff --git a/include/newsletter.inc.php b/include/newsletter.inc.php index da97493..623121f 100644 --- a/include/newsletter.inc.php +++ b/include/newsletter.inc.php @@ -47,6 +47,11 @@ class NewsLetter const GROUP_AX = 'AX'; const GROUP_EP = 'Ecole'; + // Searches on mutiple fields + const SEARCH_ALL = 'all'; + const SEARCH_TITLE = 'title'; + + // {{{ Constructor, NewsLetter retrieval (forGroup, getAll) public function __construct($id) @@ -174,7 +179,7 @@ class NewsLetter } } - return new NLIssue($id, &$this); + return new NLIssue($id, $this); } /** Create a new, empty, pending newsletter issue @@ -251,6 +256,63 @@ class NewsLetter } } + /** Returns a list of either issues or articles corresponding to the search. + * @p $search The searched pattern. + * @p $field The fields where to search, if none given, search in all possible fields. + * @return The list of object found. + */ + public function issueSearch($search, $field, $user) + { + $search = XDB::formatWildcards(XDB::WILDCARD_CONTAINS, $search); + if ($field == self::SEARCH_ALL) { + $where = '(title ' . $search . ' OR mail_title ' . $search . ' OR head ' . $search . ' OR signature ' . $search . ')'; + } elseif ($field == self::SEARCH_TITLE) { + $where = '(title ' . $search . ' OR mail_title ' . $search . ')'; + } else { + $where = $field . $search; + } + $list = XDB::fetchColumn('SELECT DISTINCT(id) + FROM newsletter_issues + WHERE nlid = {?} AND state = \'sent\' AND ' . $where . ' + ORDER BY date DESC', + $this->id); + + $issues = array(); + foreach ($list as $id) { + $issue = new NLIssue($id, $this, false); + if ($issue->checkUser($user)) { + $issues[] = $issue; + } + } + return $issues; + } + + public function articleSearch($search, $field, $user) + { + $search = XDB::formatWildcards(XDB::WILDCARD_CONTAINS, $search); + if ($field == self::SEARCH_ALL) { + $where = '(a.title ' . $search . ' OR a.body ' . $search . ' OR a.append ' . $search . ')'; + } else { + $where = 'a.' . $field . $search; + } + $list = XDB::fetchAllAssoc('SELECT i.short_name, a.aid, i.id, a.title + FROM newsletter_art AS a + INNER JOIN newsletter_issues AS i ON (a.id = i.id) + WHERE i.nlid = {?} AND i.state = \'sent\' AND ' . $where . ' + GROUP BY a.id, a.aid + ORDER BY i.date DESC, a.aid', + $this->id); + + $articles = array(); + foreach ($list as $item) { + $issue = new NLIssue($item['id'], $this, false); + if ($issue->checkUser($user)) { + $articles[] = $item; + } + } + return $articles; + } + // }}} // {{{ Subscription related function @@ -433,7 +495,7 @@ class NewsLetter /** Get the prefix leading to the page for this NL * Only X.org / AX / X groups may be seen on X.org. */ - public function prefix() + public function prefix($enforce_xnet=true) { if (!empty($GLOBALS['IS_XNET_SITE'])) { return $this->group . '/nl'; @@ -447,13 +509,13 @@ class NewsLetter return 'epletter'; default: // Don't display groups NLs on X.org - assert(false); + assert(!$enforce_xnet); } } /** Get the prefix to use for all 'admin' pages of this NL. */ - public function adminPrefix() + public function adminPrefix($enforce_xnet=true) { if (!empty($GLOBALS['IS_XNET_SITE'])) { return $this->group . '/admin/nl'; @@ -467,7 +529,7 @@ class NewsLetter return 'epletter/admin'; default: // Don't display groups NLs on X.org - assert(false); + assert(!$enforce_xnet); } } @@ -558,6 +620,7 @@ class NLIssue $this->nl = new NewsLetter($issue['nlid']); } $this->id = $id; + $this->nlid = $issue['nlid']; $this->shortname = $issue['short_name']; $this->date = $issue['date']; $this->send_before = $issue['send_before']; @@ -666,6 +729,11 @@ class NLIssue 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(); } return $success; @@ -681,7 +749,7 @@ class NLIssue { if ($this->state == self::STATE_PENDING) { $success = XDB::execute('UPDATE newsletter_issues - SET send_before = NULL, state = \'new\' + SET state = \'new\' WHERE id = {?}', $this->id); if ($success) { $this->refresh(); @@ -761,6 +829,7 @@ class NLIssue const ERROR_INVALID_SHORTNAME = 'invalid_shortname'; const ERROR_INVALID_UFC = 'invalid_ufc'; + const ERROR_TOO_LONG_UFC = 'too_long_ufc'; const ERROR_SQL_SAVE = 'sql_error'; /** Save the global properties of this NL issue (title&co). @@ -786,6 +855,11 @@ class NLIssue } if ($this->sufb->isValid() || $this->sufb->isEmpty()) { $fields['sufb_json'] = json_encode($this->sufb->export()->dict()); + // If sufb_json is too long to be store, we do not store a truncated json and notify the user. + // The limit is LONGTEXT's one, ie 2^32 = 4294967296. + if (strlen($fields['sufb_json']) > 4294967295) { + $errors[] = self::ERROR_TOO_LONG_UFC; + } } else { $errors[] = self::ERROR_INVALID_UFC; } @@ -831,9 +905,9 @@ class NLIssue } /** Save an article - * @p &$a A reference to a NLArticle object (will be modified once saved) + * @p $a A reference to a NLArticle object (will be modified once saved) */ - public function saveArticle(&$a) + public function saveArticle($a) { $this->fetchArticles(); @@ -927,7 +1001,7 @@ class NLIssue * @p $page Smarty object * @return Either 'true' (if CSS was added to a page) or the raw CSS to add (when $page is null) */ - public function css(&$page = null) + public function css($page = null) { if (!is_null($page)) { $page->addCssLink($this->nl->cssFile()); @@ -942,7 +1016,7 @@ class NLIssue * @p $page Smarty object (using the $this->nl->tplFile() template) * @p $user User to use when rendering the template */ - public function toText(&$page, $user) + public function toText($page, $user) { $this->fetchArticles(); @@ -959,7 +1033,7 @@ class NLIssue * @p $page Smarty object (using the $this->nl->tplFile() template) * @p $user User to use when rendering the template */ - public function toHtml(&$page, $user) + public function toHtml($page, $user) { $this->fetchArticles(); @@ -975,7 +1049,7 @@ class NLIssue /** Set all 'common' data for the page (those which are required for both web and email rendering) * @p $smarty Smarty object (e.g page) which should be filled */ - protected function assignData(&$smarty) + protected function assignData($smarty) { $this->fetchArticles(); @@ -985,7 +1059,15 @@ class NLIssue // }}} // {{{ Mailing - + + /** Check whether this issue is empty + * An issue is empty if the email has no title (or the default one), or no articles and an empty head. + */ + public function isEmpty() + { + return $this->title_mail == '' || $this->title_mail == 'to be continued' || (count($this->arts) == 0 && strlen($this->head) == 0); + } + /** Retrieve the 'Send before' date, in a clean format. */ public function getSendBeforeDate() @@ -1077,9 +1159,9 @@ class NLIssue WHERE id = {?}', $this->id); - $ufc = new PFC_And($this->getRecipientsUFC(), new UFC_NLSubscribed($this->nl->id, $this->id), new UFC_HasEmailRedirect()); + $ufc = new PFC_And($this->getRecipientsUFC(), new UFC_NLSubscribed($this->nl->id, $this->id), new UFC_HasValidEmail()); $emailsCount = 0; - $uf = new UserFilter($ufc); + $uf = new UserFilter($ufc, array(new UFO_IsAdmin(), new UFO_Uid())); $limit = new PlLimit(self::BATCH_SIZE); while (true) { @@ -1111,7 +1193,8 @@ class NLIssue class NLArticle { // Maximum number of lines per article - const MAX_LINES_PER_ARTICLE = 9; + const MAX_LINES_PER_ARTICLE = 8; + const MAX_CHARACTERS_PER_LINE = 68; // {{{ properties @@ -1199,17 +1282,30 @@ class NLArticle public function check() { - $text = MiniWiki::WikiToText($this->body); - $arr = explode("\n",wordwrap($text,68)); - $c = 0; - foreach ($arr as $line) { - if (trim($line)) { - $c++; + $rest = $this->remain(); + + return $rest['remaining_lines'] >= 0; + } + + // }}} + // {{{ function remain() + + public function remain() + { + $text = MiniWiki::WikiToText($this->body); + $array = explode("\n", wordwrap($text, self::MAX_CHARACTERS_PER_LINE)); + $lines_count = 0; + foreach ($array as $line) { + if (trim($line) != '') { + ++$lines_count; } } - return $c < self::MAX_LINES_PER_ARTICLE; - } + return array( + 'remaining_lines' => self::MAX_LINES_PER_ARTICLE - $lines_count, + 'remaining_characters_for_last_line' => self::MAX_CHARACTERS_PER_LINE - strlen($array[count($array) - 1]) + ); + } // }}} // {{{ function parseUrlsFromArticle()