/** * Display a list of latest whiteboard entries * * @return void */ public function displayTask() { if (!User::authorise('core.manage', $this->_option)) { $ip = Request::ip(); $ips = explode(',', $this->config->get('whitelist', '')); $ips = array_map('trim', $ips); if (!in_array($ip, $ips)) { $ips = gethostbynamel($_SERVER['SERVER_NAME']); if (!in_array($ip, $ips)) { $ips = gethostbynamel('localhost'); if (!in_array($ip, $ips)) { header("HTTP/1.1 404 Not Found"); exit; } } } } Request::setVar('no_html', 1); Request::setVar('tmpl', 'component'); $now = Date::toSql(); $results = Job::all()->whereEquals('state', 1)->where('next_run', '<=', Date::toLocal('Y-m-d H:i:s'))->whereEquals('publish_up', '0000-00-00 00:00:00', 1)->orWhere('publish_up', '<=', $now, 1)->resetDepth()->whereEquals('publish_down', '0000-00-00 00:00:00', 1)->orWhere('publish_down', '>', $now, 1)->rows(); $output = new stdClass(); $output->jobs = array(); if ($results) { foreach ($results as $job) { if ($job->get('active') || !$job->isAvailable()) { continue; } // Show related content $job->mark('start_run'); $results = Event::trigger('cron.' . $job->get('event'), array($job)); if ($results && is_array($results)) { // Set it as active in case there were multiple plugins called on // the event. This is to ensure ALL processes finished. $job->set('active', 1); $job->save(); foreach ($results as $result) { if ($result) { $job->set('active', 0); } } } $job->mark('end_run'); $job->set('last_run', Date::toLocal('Y-m-d H:i:s')); //Date::toSql()); $job->set('next_run', $job->nextRun()); $job->save(); $output->jobs[] = $job->toArray(); } } $this->view->set('no_html', Request::getInt('no_html', 0))->set('output', $output)->display(); }
/** * Issue master DOI for tool resources if does not exist * * @param object $job \Components\Cron\Models\Job * @return boolean */ public function updateResourceRanking(\Components\Cron\Models\Job $job) { $processed = array(); $params = $job->get('params'); $limit = $params->get('resource_limit', 100); if (!is_numeric($limit) || $limit <= 0 || $limit > 1000) { $limit = 100; } switch (intval($params->get('resource_frequency', 7))) { case 7: // Once a week, start of the week $d = new \DateTime('-' . gmdate('w') . ' days'); break; case 14: // Find a start point if (!$params->get('start_point')) { $d = new \DateTime('-' . gmdate('w') . ' days'); $timestamp = $d->format('Y-m-d') . ' 00:00:00'; $params->set('start_point', $d->format('Y-m-d') . ' 00:00:00'); } $now = Date::toSql(); if ($now > $params->get('start_point')) { $d = new \DateTime($params->get('start_point')); $d->modify('+2 week'); $params->set('start_point', $d->format('Y-m-d') . ' 00:00:00'); $job->set('params', $params->toString()); $job->store(false); $job->set('params', $params); } $d = new \DateTime($params->get('start_point')); break; case 21: // Find a start point if (!$params->get('start_point')) { $d = new \DateTime('-' . gmdate('w') . ' days'); $timestamp = $d->format('Y-m-d') . ' 00:00:00'; $params->set('start_point', $d->format('Y-m-d') . ' 00:00:00'); } $now = Date::toSql(); if ($now > $params->get('start_point')) { $d = new \DateTime($params->get('start_point')); $d->modify('+3 week'); $params->set('start_point', $d->format('Y-m-d') . ' 00:00:00'); $job->set('params', $params->toString()); $job->store(false); $job->set('params', $params); } $d = new \DateTime($params->get('start_point')); break; case 30: // Once a week, start of the week $d = new \DateTime('first day of this month'); break; } $timestamp = $d->format('Y-m-d') . ' 00:00:00'; $database = App::get('db'); // Get all resources that haven't been ranked $sql = "SELECT r.id, r.ranking, r.ranked\n\t\t\t\tFROM `#__resources` AS r\n\t\t\t\tWHERE r.standalone=1\n\t\t\t\tAND r.state=1\n\t\t\t\tAND (r.ranked = '0000-00-00 00:00:00' OR r.ranked < " . $database->quote($timestamp) . ")\n\t\t\t\tORDER BY r.ranked ASC\n\t\t\t\tLIMIT {$limit}"; $database->setQuery($sql); $queued = $database->loadObjectList(); // Loop through each resource and rank it foreach ($queued as $item) { if (in_array($item->id, $processed)) { continue; } //if ($resource->rank()) //{ // mark as sent and save $resource->ranked = Date::toSql(); //$resource->store(); //} $processed[] = $item->id; } return true; }
/** * Email instructor course digest * * @param object $job \Components\Cron\Models\Job * @return boolean */ public function emailInstructorDigest(\Components\Cron\Models\Job $job) { $database = \App::get('db'); $cconfig = Component::params('com_courses'); Lang::load('com_courses') || Lang::load('com_courses', PATH_CORE . DS . 'components' . DS . 'com_courses' . DS . 'site'); $from = array('name' => Config::get('sitename') . ' ' . Lang::txt('COM_COURSES'), 'email' => Config::get('mailfrom')); $subject = Lang::txt('COM_COURSES') . ': ' . Lang::txt('COM_COURSES_SUBJECT_EMAIL_DIGEST'); require_once PATH_CORE . DS . 'components' . DS . 'com_courses' . DS . 'models' . DS . 'courses.php'; $course_id = 0; $params = $job->get('params'); if (isset($params) && is_object($params)) { $course_id = $params->get('course'); } $coursesObj = new \Components\Courses\Models\Courses(); if ($course_id) { $courses = array($coursesObj->course($course_id)); } else { $courses = $coursesObj->courses(); } if (isset($courses) && count($courses) > 0) { foreach ($courses as $course) { if (!$course->isAvailable()) { continue; } $mailed = array(); $managers = $course->managers(); $enrollments = $course->students(array('count' => true)); $offerings = $course->offerings(); if (isset($offerings) && count($offerings) > 0) { foreach ($offerings as $offering) { if (!$offering->isAvailable()) { continue; } $offering->gradebook()->refresh(); $passing = $offering->gradebook()->countPassing(false); $failing = $offering->gradebook()->countFailing(false); if (isset($managers) && count($managers) > 0) { foreach ($managers as $manager) { // Get the user's account $user = User::getInstance($manager->get('user_id')); if (!$user->get('id')) { continue; } // Try to ensure no duplicates if (in_array($user->get('username'), $mailed)) { continue; } // Only mail instructors (i.e. not managers) if ($manager->get('role_alias') != 'instructor') { continue; } // Get discussion stats and posts require_once PATH_CORE . DS . 'components' . DS . 'com_forum' . DS . 'tables' . DS . 'post.php'; $postsTbl = new \Components\Forum\Tables\Post($database); $filters = array('scope' => 'course', 'scope_id' => $offering->get('id'), 'state' => 1, 'sort' => 'created', 'sort_Dir' => 'DESC', 'limit' => 100); $posts = $postsTbl->find($filters); $posts_cnt = count($posts); $latest = array(); $latest_cnt = 0; if (isset($posts) && $posts_cnt > 0) { foreach ($posts as $post) { if (strtotime($post->created) > strtotime('-1 day')) { $latest[] = $post; } else { break; } } $latest_cnt = count($latest); } $eview = new \Hubzero\Component\View(array('base_path' => PATH_CORE . DS . 'components' . DS . 'com_courses' . DS . 'site', 'name' => 'emails', 'layout' => 'digest_plain')); $eview->option = 'com_courses'; $eview->controller = 'courses'; $eview->delimiter = '~!~!~!~!~!~!~!~!~!~!'; $eview->course = $course; $eview->enrollments = $enrollments; $eview->passing = $passing; $eview->failing = $failing; $eview->offering = $offering; $eview->posts_cnt = $posts_cnt; $eview->latest = $latest; $eview->latest_cnt = $latest_cnt; $plain = $eview->loadTemplate(); $plain = str_replace("\n", "\r\n", $plain); // HTML $eview->setLayout('digest_html'); $html = $eview->loadTemplate(); $html = str_replace("\n", "\r\n", $html); // Build message $message = new \Hubzero\Mail\Message(); $message->setSubject($subject)->addFrom($from['email'], $from['name'])->addTo($user->get('email'), $user->get('name'))->addHeader('X-Component', 'com_courses')->addHeader('X-Component-Object', 'courses_instructor_digest'); $message->addPart($plain, 'text/plain'); $message->addPart($html, 'text/html'); // Send mail if (!$message->send()) { $this->setError('Failed to mail %s', $user->get('email')); } $mailed[] = $user->get('username'); } } } } } } return true; }
/** * Send emails reminding people of their open tickets * * @param object $job \Components\Cron\Models\Job * @return boolean */ public function sendTicketList(\Components\Cron\Models\Job $job) { $params = $job->get('params'); $database = App::get('db'); $sconfig = Component::params('com_support'); Lang::load('com_support') || Lang::load('com_support', PATH_CORE . DS . 'components' . DS . 'com_support' . DS . 'site'); $sql = "SELECT t.*, o.`name` AS owner_name FROM `#__support_tickets` AS t LEFT JOIN `#__users` AS o ON o.`id`=t.`owner`"; $where = array(); $where[] = "t.`type`=0"; if (is_object($params)) { if ($val = $params->get('support_ticketlist_open', 1)) { $where[] = "t.`open`=" . $val; } $statuses = array(); if (is_numeric($params->get('support_ticketlist_status1'))) { $statuses[] = $params->get('support_ticketlist_status1'); } if (is_numeric($params->get('support_ticketlist_status2'))) { $statuses[] = $params->get('support_ticketlist_status2'); } if (is_numeric($params->get('support_ticketlist_status3'))) { $statuses[] = $params->get('support_ticketlist_status3'); } if (count($statuses)) { $where[] = "t.`status` IN (" . implode(',', $statuses) . ")"; } if ($group = $params->get('support_ticketlist_group')) { $where[] = "t.`group`=" . $database->quote($group); } if ($owners = $params->get('support_ticketlist_owners')) { $usernames = explode(',', $owners); $usernames = array_map('trim', $usernames); foreach ($usernames as $k => $username) { $user = User::getInstance($username); $usernames[$k] = $database->quote($user->get('id')); } $where[] = "t.`owner` IN (" . implode(", ", $usernames) . ")"; } if ($severity = $params->get('support_ticketlist_severity')) { if ($severity != 'all') { $severities = explode(',', $severity); $severities = array_map('trim', $severities); foreach ($severities as $k => $severity) { $severities[$k] = $database->quote($severity); } $where[] = "t.`severity` IN (" . implode(", ", $severities) . ")"; } } if ($owned = intval($params->get('support_ticketlist_owned', 0))) { if ($owned == 1) { $where[] = "(t.`owner` IS NULL OR t.`owner`='0')"; } else { if ($owned == 2) { $where[] = "(t.`owner` IS NOT NULL AND t.`owner` !='0')"; } } } if ($submitters = $params->get('support_ticketlist_submitters')) { $usernames = explode(',', $submitters); $usernames = array_map('trim', $usernames); foreach ($usernames as $k => $username) { $usernames[$k] = $database->quote($username); } $where[] = "t.`login` IN (" . implode(", ", $usernames) . ")"; } if ($tags = $params->get('support_ticketlist_excludeTags')) { $tags = explode(',', $tags); $tags = array_map('trim', $tags); foreach ($tags as $k => $tag) { $tags[$k] = $database->quote($tag); } $where[] = "t.`id` NOT IN (\n\t\t\t\t\t\t\tSELECT jto.`objectid` FROM `#__tags_object` AS jto\n\t\t\t\t\t\t\tJOIN `#__tags` AS jt ON jto.`tagid`=jt.`id`\n\t\t\t\t\t\t\tWHERE jto.`tbl`='support'\n\t\t\t\t\t\t\tAND (\n\t\t\t\t\t\t\t\tjt.`tag` IN (" . implode(", ", $tags) . ") OR jt.`raw_tag` IN (" . implode(", ", $tags) . ")\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t)"; } if ($tags = $params->get('support_ticketlist_includeTags')) { $tags = explode(',', $tags); $tags = array_map('trim', $tags); foreach ($tags as $k => $tag) { $tags[$k] = $database->quote($tag); } $where[] = "t.`id` IN (\n\t\t\t\t\t\t\tSELECT jto.`objectid` FROM `#__tags_object` AS jto\n\t\t\t\t\t\t\tJOIN `#__tags` AS jt ON jto.`tagid`=jt.`id`\n\t\t\t\t\t\t\tWHERE jto.`tbl`='support'\n\t\t\t\t\t\t\tAND (\n\t\t\t\t\t\t\t\tjt.`tag` IN (" . implode(", ", $tags) . ") OR jt.`raw_tag` IN (" . implode(", ", $tags) . ")\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t)"; } if ($created = $params->get('support_ticketlist_created', '+week')) { $op = ''; switch ($created) { // Created before (older than) case '-day': $op = '<='; $timestamp = Date::modify('-1 day'); break; case '-week': $op = '<='; $timestamp = Date::modify('-1 week'); break; case '-2week': $op = '<='; $timestamp = Date::modify('-2 week'); break; case '-3week': $op = '<='; $timestamp = Date::modify('-3 week'); break; case '-month': $op = '<='; $timestamp = Date::modify('-1 month'); break; case '-6month': $op = '<='; $timestamp = Date::modify('-6 month'); break; case '-year': $op = '<='; $timestamp = Date::modify('-1 year'); break; // Created since (newer than) // Created since (newer than) case '+day': $op = '>='; $timestamp = Date::modify('-1 day'); break; case '+week': $op = '>='; $timestamp = Date::modify('-1 week'); break; case '+2week': $op = '>='; $timestamp = Date::modify('-2 week'); break; case '+3week': $op = '>='; $timestamp = Date::modify('-3 week'); break; case '+month': $op = '>='; $timestamp = Date::modify('-1 month'); break; case '+6month': $op = '>='; $timestamp = Date::modify('-6 month'); break; case '+year': $op = '>='; $timestamp = Date::modify('-1 year'); break; } if ($op) { $where[] = "t.`created`" . $op . $database->quote($timestamp->toSql()); } } if ($created = $params->get('support_ticketlist_activity', '--')) { $op = ''; switch ($created) { // Created before (older than) case '-day': $op = '<='; $timestamp = Date::modify('-1 day'); break; case '-week': $op = '<='; $timestamp = Date::modify('-1 week'); break; case '-2week': $op = '<='; $timestamp = Date::modify('-2 week'); break; case '-3week': $op = '<='; $timestamp = Date::modify('-3 week'); break; case '-month': $op = '<='; $timestamp = Date::modify('-1 month'); break; case '-6month': $op = '<='; $timestamp = Date::modify('-6 month'); break; case '-year': $op = '<='; $timestamp = Date::modify('-1 year'); break; case 'all': case '--': $op = ''; break; } if ($op) { $where[] = "(SELECT MAX(c.`created`) FROM `#__support_comments` AS c WHERE c.`ticket`=t.`id`) " . $op . $database->quote($timestamp->toSql()); } } } else { $where[] = "t.`open`=1"; } if (count($where) > 0) { $sql .= " WHERE " . implode(" AND ", $where); } $sql .= " ORDER BY t.`created` ASC LIMIT 0, 500"; $database->setQuery($sql); if (!($results = $database->loadObjectList())) { return true; } include_once PATH_CORE . DS . 'components' . DS . 'com_support' . DS . 'models' . DS . 'ticket.php'; if ($params->get('support_ticketlist_severity', 'all') != 'all') { $severities = explode(',', $params->get('support_ticketlist_severity', 'all')); } else { include_once PATH_CORE . DS . 'components' . DS . 'com_support' . DS . 'helpers' . DS . 'utilities.php'; $severities = \Components\Support\Helpers\Utilities::getSeverities($sconfig->get('severities')); } $from = array(); $from['name'] = Config::get('sitename') . ' ' . Lang::txt('COM_SUPPORT'); $from['email'] = Config::get('mailfrom'); $from['multipart'] = md5(date('U')); // Set mail additional args (mail return path - used for bounces) if ($host = Request::getVar('HTTP_HOST', '', 'server')) { $args = '-f hubmail-bounces@' . $host; } $subject = Lang::txt('COM_SUPPORT') . ': ' . Lang::txt('COM_SUPPORT_TICKETS'); $usernames = array(); if ($users = $params->get('support_ticketlist_notify')) { $usernames = explode(',', $users); $usernames = array_map('trim', $usernames); } $mailed = array(); foreach ($usernames as $owner) { if ($owner == '{config.mailfrom}') { $name = Config::get('mailfrom'); $email = Config::get('mailfrom'); } else { if (strstr($owner, '@')) { $name = $owner; $email = $owner; } else { // Get the user's account $user = User::getInstance($owner); if (!is_object($user) || !$user->get('id')) { continue; } $name = $user->get('name'); $email = $user->get('email'); } } // Try to ensure no duplicates if (in_array($email, $mailed)) { continue; } $eview = new \Hubzero\Mail\View(array('base_path' => PATH_CORE . DS . 'components' . DS . 'com_support' . DS . 'site', 'name' => 'emails', 'layout' => 'ticketlist_plain')); $eview->option = 'com_support'; $eview->controller = 'tickets'; $eview->delimiter = '~!~!~!~!~!~!~!~!~!~!'; $eview->boundary = $from['multipart']; $eview->tickets = $results; $eview->config = $sconfig; $plain = $eview->loadTemplate(false); $plain = str_replace("\n", "\r\n", $plain); // HTML $eview->setLayout('ticketlist_html'); $html = $eview->loadTemplate(); $html = str_replace("\n", "\r\n", $html); // Build message $message = new \Hubzero\Mail\Message(); $message->setSubject($subject)->addFrom($from['email'], $from['name'])->addTo($email, $name)->addHeader('X-Component', 'com_support')->addHeader('X-Component-Object', 'support_ticket_list'); $message->addPart($plain, 'text/plain'); $message->addPart($html, 'text/html'); // Send mail if (!$message->send()) { //$this->setError(Lang::txt('Failed to mail %s', $fullEmailAddress)); Log::error('CRON email failed: ' . Lang::txt('Failed to mail %s', $email)); } $mailed[] = $email; } return true; }
/** * Run any scheduled cron tasks * * @return void */ public function displayTask() { // If the current user doesn't have access to manage the component, // try to see if their IP address is in the whtielist. // Otherwise, we stop any further code execution. if (!User::authorise('core.manage', $this->_option)) { $ip = Request::ip(); $ips = explode(',', $this->config->get('whitelist', '')); $ips = array_map('trim', $ips); if (!in_array($ip, $ips)) { $ips = gethostbynamel($_SERVER['SERVER_NAME']); if (!in_array($ip, $ips)) { $ips = gethostbynamel('localhost'); if (!in_array($ip, $ips)) { header("HTTP/1.1 404 Not Found"); exit; } } } } // Forcefully do NOT render the template // (extra processing that's not needed) Request::setVar('no_html', 1); Request::setVar('tmpl', 'component'); $now = Date::toSql(); // Get the list of jobs that should be run $results = Job::all()->whereEquals('state', 1)->where('next_run', '<=', Date::toLocal('Y-m-d H:i:s'))->whereEquals('publish_up', '0000-00-00 00:00:00', 1)->orWhere('publish_up', '<=', $now, 1)->resetDepth()->whereEquals('publish_down', '0000-00-00 00:00:00', 1)->orWhere('publish_down', '>', $now, 1)->rows(); $output = new stdClass(); $output->jobs = array(); if ($results) { foreach ($results as $job) { if ($job->get('active') || !$job->isAvailable()) { continue; } // Show related content $job->mark('start_run'); $results = Event::trigger('cron.' . $job->get('event'), array($job)); if ($results && is_array($results)) { // Set it as active in case there were multiple plugins called on // the event. This is to ensure ALL processes finished. $job->set('active', 1); $job->save(); foreach ($results as $result) { if ($result) { $job->set('active', 0); } } } $job->mark('end_run'); $job->set('last_run', Date::toLocal('Y-m-d H:i:s')); //Date::toSql()); $job->set('next_run', $job->nextRun()); $job->save(); $output->jobs[] = $job->toArray(); } } // Output any data from the jobs that ran // Largely used for debugging/monitoring purposes $this->view->set('no_html', Request::getInt('no_html', 0))->set('output', $output)->display(); }
/** * Sets the state of one or more entries * * @param integer $state The state to set entries to * @return void */ public function stateTask($state = 0) { // Check for request forgeries Request::checkToken(['get', 'post']); // Incoming $state = $this->_task == 'publish' ? 1 : 0; $ids = Request::getVar('id', array()); $ids = !is_array($ids) ? array($ids) : $ids; // Check for an ID if (count($ids) < 1) { $action = $state == 1 ? Lang::txt('COM_CRON_STATE_UNPUBLISH') : Lang::txt('COM_CRON_STATE_PUBLISH'); App::redirect(Route::url('index.php?option=' . $this->_option . '&controller=' . $this->_controller, false), Lang::txt('COM_CRON_ERROR_SELECT_ITEMS', $action), 'error'); return; } $total = 0; foreach ($ids as $id) { // Update record(s) $row = Job::oneOrFail(intval($id)); $row->set('state', $state); if (!$row->save()) { Notify::error($row->getError()); continue; } $total++; } // Set message if ($state == 1) { Notify::success(Lang::txt('COM_CRON_ITEMS_PUBLISHED', $total)); } else { Notify::success(Lang::txt('COM_CRON_ITEMS_UNPUBLISHED', $total)); } App::redirect(Route::url('index.php?option=' . $this->_option, false)); }
/** * Sets the state of one or more entries * * @param integer $state The state to set entries to * @return void */ public function stateTask($state = 0) { // Check for request forgeries Request::checkToken(['get', 'post']); if (!User::authorise('core.edit.state', $this->_option)) { App::abort(403, Lang::txt('JERROR_ALERTNOAUTHOR')); } // Incoming $state = $this->_task == 'publish' ? 1 : 0; $ids = Request::getVar('id', array()); $ids = !is_array($ids) ? array($ids) : $ids; // Check for an ID if (count($ids) < 1) { $action = $state == 1 ? Lang::txt('COM_CRON_STATE_UNPUBLISH') : Lang::txt('COM_CRON_STATE_PUBLISH'); Notify::warning(Lang::txt('COM_CRON_ERROR_SELECT_ITEMS', $action)); return $this->cancelTask(); } $total = 0; foreach ($ids as $id) { // Update record(s) $row = Job::oneOrFail(intval($id)); $row->set('state', $state); if (!$row->save()) { Notify::error($row->getError()); continue; } $total++; } // Set message if ($total) { if ($state == 1) { Notify::success(Lang::txt('COM_CRON_ITEMS_PUBLISHED', $total)); } else { Notify::success(Lang::txt('COM_CRON_ITEMS_UNPUBLISHED', $total)); } } $this->cancelTask(); }
/** * Send emails to authors with the monthly stats * * @param object $job \Components\Cron\Models\Job * @return boolean */ public function sendAuthorStats(\Components\Cron\Models\Job $job) { $database = App::get('db'); $pconfig = Component::params('com_publications'); // Get some params $limit = $pconfig->get('limitStats', 5); $image = $pconfig->get('email_image', ''); Lang::load('com_publications', PATH_CORE) || Lang::load('com_publications', PATH_CORE . DS . 'components' . DS . 'com_publications' . DS . 'site'); // Is logging enabled? if (is_file(PATH_CORE . DS . 'components' . DS . 'com_publications' . DS . 'tables' . DS . 'logs.php')) { require_once PATH_CORE . DS . 'components' . DS . 'com_publications' . DS . 'tables' . DS . 'logs.php'; } else { $this->setError('Publication logs not present on this hub, cannot email stats to authors'); return false; } // Helpers require_once PATH_CORE . DS . 'components' . DS . 'com_members' . DS . 'helpers' . DS . 'imghandler.php'; require_once PATH_CORE . DS . 'components' . DS . 'com_publications' . DS . 'helpers' . DS . 'html.php'; // Get all registered authors who subscribed to email $query = "SELECT A.user_id, P.picture "; $query .= " FROM #__publication_authors as A "; $query .= " JOIN #__xprofiles as P ON A.user_id = P.uidNumber "; $query .= " WHERE P.mailPreferenceOption != 0 "; // either 1 (set to YES) or -1 (never set) $query .= " AND A.user_id > 0 AND A.status=1 "; // If we need to restrict to selected authors $params = $job->get('params'); if (is_object($params) && $params->get('userids')) { $apu = explode(',', $params->get('userids')); $apu = array_map('trim', $apu); $query .= " AND A.user_id IN ("; $tquery = ''; foreach ($apu as $a) { $tquery .= "'" . $a . "',"; } $tquery = substr($tquery, 0, strlen($tquery) - 1); $query .= $tquery . ") "; } $query .= " GROUP BY A.user_id "; $database->setQuery($query); if (!($authors = $database->loadObjectList())) { return true; } // Set email config $from = array('name' => Config::get('fromname') . ' ' . Lang::txt('Publications'), 'email' => Config::get('mailfrom'), 'multipart' => md5(date('U'))); $subject = Lang::txt('Monthly Publication Usage Report'); $i = 0; foreach ($authors as $author) { // Get the user's account $user = User::getInstance($author->user_id); if (!$user->get('id')) { // Skip if not registered continue; } // Get pub stats for each author $pubLog = new \Components\Publications\Tables\Log($database); $pubstats = $pubLog->getAuthorStats($author->user_id); if (!$pubstats || !count($pubstats)) { // Nothing to send continue; } // Plain text $eview = new \Hubzero\Plugin\View(array('folder' => 'cron', 'element' => 'publications', 'name' => 'emails', 'layout' => 'stats_plain')); $eview->option = 'com_publications'; $eview->controller = 'publications'; $eview->user = $user; $eview->pubstats = $pubstats; $eview->limit = $limit; $eview->image = $image; $eview->config = $pconfig; $eview->totals = $pubLog->getTotals($author->user_id, 'author'); $plain = $eview->loadTemplate(); $plain = str_replace("\n", "\r\n", $plain); // HTML $eview->setLayout('stats_html'); $html = $eview->loadTemplate(); $html = str_replace("\n", "\r\n", $html); // Build message $message = new \Hubzero\Mail\Message(); $message->setSubject($subject)->addFrom($from['email'], $from['name'])->addTo($user->get('email'), $user->get('name'))->addHeader('X-Component', 'com_publications')->addHeader('X-Component-Object', 'publications'); $message->addPart($plain, 'text/plain'); $message->addPart($html, 'text/html'); // Send mail if (!$message->send()) { $this->setError(Lang::txt('PLG_CRON_PUBLICATIONS_ERROR_FAILED_TO_MAIL', $user->get('email'))); } $mailed[] = $user->get('email'); } return true; }
/** * Processes any queued newsletter mailings. * * @param object $job \Components\Cron\Models\Job * @return boolean */ public function processMailings(\Components\Cron\Models\Job $job) { // load needed libraries require_once PATH_CORE . DS . 'components' . DS . 'com_newsletter' . DS . 'tables' . DS . 'mailing.recipient.php'; require_once PATH_CORE . DS . 'components' . DS . 'com_newsletter' . DS . 'helpers' . DS . 'helper.php'; // needed vars $limit = 25; $processed = array(); // do we have a param defined limit $params = $job->get('params'); if (is_object($params) && $params->get('newsletter_queue_limit')) { $paramDefinedLimit = $params->get('newsletter_queue_limit'); if (is_numeric($paramDefinedLimit) && $paramDefinedLimit > 0 && $paramDefinedLimit < 100) { $limit = $paramDefinedLimit; } } // create needed objects $database = App::get('db'); // get all queued mailing recipients $sql = "SELECT nmr.id AS mailing_recipientid, nm.id AS mailingid, nm.nid AS newsletterid, nm.lid AS mailinglistid, nmr.email, nm.subject, nm.html_body, nm.plain_body, nm.headers, nm.args, nm.tracking\n\t\t\t\tFROM `#__newsletter_mailings` AS nm, `#__newsletter_mailing_recipients` AS nmr\n\t\t\t\tWHERE nm.id=nmr.mid\n\t\t\t\tAND nmr.status='queued'\n\t\t\t\tAND nm.deleted=0\n\t\t\t\tAND UTC_TIMESTAMP() >= nm.date\n\t\t\t\tORDER BY nmr.date_added\n\t\t\t\tLIMIT {$limit}"; $database->setQuery($sql); $queuedEmails = $database->loadObjectList(); // loop through each newsletter recipient, prepare and mail foreach ($queuedEmails as $queuedEmail) { if (in_array($queuedEmail->email, $processed)) { continue; } // get tracking & unsubscribe token $emailToken = \Components\Newsletter\Helpers\Helper::generateMailingToken($queuedEmail); // if tracking is on add it to email if ($queuedEmail->tracking) { $queuedEmail->html_body = \Components\Newsletter\Helpers\Helper::addTrackingToEmailMessage($queuedEmail->html_body, $emailToken); } // create unsubscribe link $unsubscribeMailtoLink = ''; $unsubscribeLink = 'https://' . $_SERVER['SERVER_NAME'] . '/newsletter/unsubscribe?e=' . urlencode($queuedEmail->email) . '&t=' . $emailToken; // add unsubscribe link - placeholder & in header (must do after adding tracking!!) $queuedEmail->html_body = str_replace("{{UNSUBSCRIBE_LINK}}", $unsubscribeLink, $queuedEmail->html_body); $queuedEmail->headers = str_replace("{{UNSUBSCRIBE_LINK}}", $unsubscribeLink, $queuedEmail->headers); $queuedEmail->headers = str_replace("{{UNSUBSCRIBE_MAILTO_LINK}}", $unsubscribeMailtoLink, $queuedEmail->headers); // add mailing id to header $queuedEmail->headers = str_replace("{{CAMPAIGN_MAILING_ID}}", $queuedEmail->mailingid, $queuedEmail->headers); // create new message $message = new \Hubzero\Mail\Message(); // add headers foreach (explode("\r\n", $queuedEmail->headers) as $header) { $parts = array_map("trim", explode(':', $header)); switch ($parts[0]) { case 'From': if (preg_match("/\\\"([^\"]*)\\\"\\s<([^>]*)>/ux", $parts[1], $matches)) { $message->setFrom(array($matches[2] => $matches[1])); } break; case 'Reply-To': if (preg_match("/\\\"([^\"]*)\\\"\\s<([^>]*)>/ux", $parts[1], $matches)) { $message->setReplyTo(array($matches[2] => $matches[1])); } break; case 'Importance': case 'X-Priority': case 'X-MSMail-Priority': $priority = isset($parts[1]) && in_array($parts[1], array(1, 2, 3, 4, 5)) ? $parts[1] : 3; $message->setPriority($priority); break; default: if (isset($parts[1])) { $message->addHeader($parts[0], $parts[1]); } } } // build message object and send $message->setSubject($queuedEmail->subject)->setTo($queuedEmail->email)->setBody($queuedEmail->plain_body, 'text/plain')->addPart($queuedEmail->html_body, 'text/html'); // mail message if ($message->send()) { // add to process email array $processed[] = $queuedEmail->email; // load recipient object $newsletterMailingRecipient = new \Components\Newsletter\Tables\MailingRecipient($database); $newsletterMailingRecipient->load($queuedEmail->mailing_recipientid); // mark as sent and save $newsletterMailingRecipient->status = 'sent'; $newsletterMailingRecipient->date_sent = Date::toSql(); $newsletterMailingRecipient->save($newsletterMailingRecipient); } } return true; }