Example #1
0
define('WT_DEBUG_SQL', false);
define('WT_REQUIRED_MYSQL_VERSION', '5.0.13');
define('WT_REQUIRED_PHP_VERSION', '5.3.2');
define('WT_MODULES_DIR', 'modules_v3/');
define('WT_ROOT', '');
define('WT_CLIENT_IP', $_SERVER['REMOTE_ADDR']);
if (file_exists(WT_DATA_DIR . WT_CONFIG_FILE)) {
    header('Location: index.php');
    return;
}
if (version_compare(PHP_VERSION, WT_REQUIRED_PHP_VERSION) < 0) {
    echo '<h1>Sorry, the setup wizard cannot start.</h1>', '<p>This server is running PHP version ', PHP_VERSION, '</p>', '<p>PHP ', WT_REQUIRED_PHP_VERSION, ' (or any later version) is required</p>';
    return;
}
Session::start();
define('WT_LOCALE', I18N::init(Filter::post('lang', '[a-zA-Z-]+', Filter::get('lang', '[a-zA-Z-]+'))));
header('Content-Type: text/html; charset=UTF-8');
?>
<!DOCTYPE html>
<html <?php 
echo I18N::htmlAttributes();
?>
>
<head>
	<meta charset="UTF-8">
	<title>
		webtrees setup wizard
	</title>
	<style type="text/css">
		body {color: black; background-color: white; font: 14px tahoma, arial, helvetica, sans-serif; padding:10px; }
		a {color: black; font-weight: normal; text-decoration: none;}
Example #2
0
 /**
  * A list of common countries.
  *
  * @return string
  */
 public function commonCountriesList()
 {
     $countries = $this->statsPlaces();
     if (empty($countries)) {
         return '';
     }
     $top10 = array();
     $i = 1;
     // Get the country names for each language
     $country_names = array();
     foreach (I18N::activeLocales() as $locale) {
         I18N::init($locale->languageTag());
         $all_countries = $this->getAllCountries();
         foreach ($all_countries as $country_code => $country_name) {
             $country_names[$country_name] = $country_code;
         }
     }
     I18N::init(WT_LOCALE);
     $all_db_countries = array();
     foreach ($countries as $place) {
         $country = trim($place['country']);
         if (array_key_exists($country, $country_names)) {
             if (!isset($all_db_countries[$country_names[$country]][$country])) {
                 $all_db_countries[$country_names[$country]][$country] = (int) $place['tot'];
             } else {
                 $all_db_countries[$country_names[$country]][$country] += (int) $place['tot'];
             }
         }
     }
     // get all the user’s countries names
     $all_countries = $this->getAllCountries();
     foreach ($all_db_countries as $country_code => $country) {
         $top10[] = '<li>';
         foreach ($country as $country_name => $tot) {
             $tmp = new Place($country_name, $this->tree);
             $place = '<a href="' . $tmp->getURL() . '" class="list_item">' . $all_countries[$country_code] . '</a>';
             $top10[] .= $place . ' - ' . I18N::number($tot);
         }
         $top10[] .= '</li>';
         if ($i++ == 10) {
             break;
         }
     }
     $top10 = implode('', $top10);
     return '<ul>' . $top10 . '</ul>';
 }
Example #3
0
     }
 } else {
     $user = User::find($user_id);
     if ($user && $username && $real_name) {
         $user->setEmail($email);
         $user->setUserName($username);
         $user->setRealName($real_name);
         if ($pass1 !== null && $pass1 === $pass2) {
             $user->setPassword($pass1);
         }
     }
 }
 if ($user) {
     // Approving for the first time? Send a confirmation email
     if ($approved && !$user->getPreference('verified_by_admin') && $user->getPreference('sessiontime') == 0) {
         I18N::init($user->getPreference('language'));
         Mail::systemMessage($WT_TREE, $user, I18N::translate('Approval of account at %s', WT_BASE_URL), I18N::translate('The administrator at the webtrees site %s has approved your application for an account. You may now sign in by accessing the following link: %s', WT_BASE_URL, WT_BASE_URL));
     }
     $user->setPreference('theme', $theme)->setPreference('language', $language)->setPreference('TIMEZONE', $timezone)->setPreference('contactmethod', $contact_method)->setPreference('comment', $comment)->setPreference('auto_accept', $auto_accept ? '1' : '0')->setPreference('visibleonline', $visible_online ? '1' : '0')->setPreference('verified', $verified ? '1' : '0')->setPreference('verified_by_admin', $approved ? '1' : '0');
     // We cannot change our own admin status. Another admin will need to do it.
     if ($user->getUserId() !== Auth::id()) {
         $user->setPreference('canadmin', $canadmin ? '1' : '0');
     }
     foreach (Tree::getAll() as $tree) {
         $tree->setUserPreference($user, 'gedcomid', Filter::post('gedcomid' . $tree->getTreeId(), WT_REGEX_XREF));
         $tree->setUserPreference($user, 'canedit', Filter::post('canedit' . $tree->getTreeId(), implode('|', array_keys($ALL_EDIT_OPTIONS))));
         if (Filter::post('gedcomid' . $tree->getTreeId(), WT_REGEX_XREF)) {
             $tree->setUserPreference($user, 'RELATIONSHIP_PATH_LENGTH', Filter::postInteger('RELATIONSHIP_PATH_LENGTH' . $tree->getTreeId(), 0, 10, 0));
         } else {
             // Do not allow a path length to be set if the individual ID is not
             $tree->setUserPreference($user, 'RELATIONSHIP_PATH_LENGTH', null);
namespace Fisharebest\Webtrees;

use PDO;
use PDOException;
define('WT_SCRIPT_NAME', 'site-unavailable.php');
// This script does not load session.php.
// session.php won’t run until a configuration file and database connection exist...
// This next block of code is a minimal version of session.php
define('WT_WEBTREES', 'webtrees');
define('WT_BASE_URL', '');
define('WT_ROOT', '');
define('WT_DATA_DIR', realpath('data') . DIRECTORY_SEPARATOR);
define('WT_MODULES_DIR', 'modules_v3/');
require 'vendor/autoload.php';
Session::start();
define('WT_LOCALE', I18N::init());
http_response_code(503);
header('Content-Type: text/html; charset=UTF-8');
// The page which redirected here may have provided an error message.
$messages = '';
foreach (FlashMessages::getMessages() as $message) {
    $messages .= '<blockquote>' . Filter::escapeHtml($message->text) . '</blockquote>';
}
// If we can't connect to the database at all, give the reason why
$config_ini_php = file_exists('data/config.ini.php') && parse_ini_file('data/config.ini.php');
if (is_array($config_ini_php) && array_key_exists('dbhost', $config_ini_php) && array_key_exists('dbport', $config_ini_php) && array_key_exists('dbuser', $config_ini_php) && array_key_exists('dbpass', $config_ini_php) && array_key_exists('dbname', $config_ini_php)) {
    try {
        new PDO('mysql:host=' . $config_ini_php['dbhost'] . ';port=' . $config_ini_php['dbport'] . ';dbname=' . $config_ini_php['dbname'], $config_ini_php['dbuser'], $config_ini_php['dbpass'], array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_OBJ, PDO::ATTR_CASE => PDO::CASE_LOWER, PDO::ATTR_AUTOCOMMIT => true));
    } catch (PDOException $ex) {
        $messages .= '<p>' . I18N::translate('The database reported the following error message:') . '</p>';
        $messages .= '<blockquote>' . $ex->getMessage() . '</blockquote>';
Example #5
0
     } else {
         http_response_code(406);
     }
     break;
 case 'delete-user':
     $user = User::find(Filter::postInteger('user_id'));
     if ($user && Auth::isAdmin() && Auth::user() !== $user) {
         Log::addAuthenticationLog('Deleted user: '******'language':
     // Change the current language
     $language = Filter::post('language');
     try {
         I18N::init($language);
         Session::put('locale', $language);
         // Remember our selection
         Auth::user()->setPreference('language', $language);
     } catch (\Exception $ex) {
         // Request for a non-existant language.
         http_response_code(406);
     }
     break;
 case 'masquerade':
     $user = User::find(Filter::postInteger('user_id'));
     if ($user && Auth::isAdmin() && Auth::user() !== $user) {
         Log::addAuthenticationLog('Masquerade as user: ' . $user->getUserName());
         Auth::login($user);
     } else {
         http_response_code(406);
Example #6
0
/**
 * Add a message to a user's inbox
 *
 * @param string[] $message
 *
 * @return bool
 */
function addMessage($message)
{
    global $WT_TREE;
    $success = true;
    $sender = User::findByIdentifier($message['from']);
    $recipient = User::findByIdentifier($message['to']);
    // Sender may not be a webtrees user
    if ($sender) {
        $sender_email = $sender->getEmail();
        $sender_real_name = $sender->getRealName();
    } else {
        $sender_email = $message['from'];
        $sender_real_name = $message['from_name'];
    }
    // Send a copy of the copy message back to the sender.
    if ($message['method'] !== 'messaging') {
        // Switch to the sender’s language.
        if ($sender) {
            I18N::init($sender->getPreference('language'));
        }
        $copy_email = $message['body'];
        if (!empty($message['url'])) {
            $copy_email .= Mail::EOL . Mail::EOL . '--------------------------------------' . Mail::EOL . I18N::translate('This message was sent while viewing the following URL: ') . $message['url'] . Mail::EOL;
        }
        if ($sender) {
            // Message from a logged-in user
            $copy_email = I18N::translate('You sent the following message to a webtrees user:'******' ' . $recipient->getRealNameHtml() . Mail::EOL . Mail::EOL . $copy_email;
        } else {
            // Message from a visitor
            $copy_email = I18N::translate('You sent the following message to a webtrees administrator:') . Mail::EOL . Mail::EOL . Mail::EOL . $copy_email;
        }
        $success = $success && Mail::send($WT_TREE, $sender_email, $sender_real_name, Site::getPreference('SMTP_FROM_NAME'), $WT_TREE->getPreference('title'), I18N::translate('webtrees message') . ' - ' . $message['subject'], $copy_email);
    }
    // Switch to the recipient’s language.
    I18N::init($recipient->getPreference('language'));
    if (isset($message['from_name'])) {
        $message['body'] = I18N::translate('Your name') . ' ' . $message['from_name'] . Mail::EOL . I18N::translate('Email address') . ' ' . $message['from_email'] . Mail::EOL . Mail::EOL . $message['body'];
    }
    // Add another footer - unless we are an admin
    if (!Auth::isAdmin()) {
        if (!empty($message['url'])) {
            $message['body'] .= Mail::EOL . Mail::EOL . '--------------------------------------' . Mail::EOL . I18N::translate('This message was sent while viewing the following URL: ') . $message['url'] . Mail::EOL;
        }
    }
    if (empty($message['created'])) {
        $message['created'] = gmdate("D, d M Y H:i:s T");
    }
    if ($message['method'] !== 'messaging3' && $message['method'] !== 'mailto' && $message['method'] !== 'none') {
        Database::prepare("INSERT INTO `##message` (sender, ip_address, user_id, subject, body) VALUES (? ,? ,? ,? ,?)")->execute(array($message['from'], WT_CLIENT_IP, $recipient->getUserId(), $message['subject'], str_replace('<br>', '', $message['body'])));
    }
    if ($message['method'] !== 'messaging') {
        if ($sender) {
            $original_email = I18N::translate('The following message has been sent to your webtrees user account from ');
            $original_email .= $sender->getRealNameHtml();
        } else {
            $original_email = I18N::translate('The following message has been sent to your webtrees user account from ');
            if (!empty($message['from_name'])) {
                $original_email .= $message['from_name'];
            } else {
                $original_email .= $message['from'];
            }
        }
        $original_email .= Mail::EOL . Mail::EOL . $message['body'];
        $success = $success && Mail::send($WT_TREE, $recipient->getEmail(), $recipient->getRealName(), $sender_email, $sender_real_name, I18N::translate('webtrees message') . ' - ' . $message['subject'], $original_email);
    }
    I18N::init(WT_LOCALE);
    // restore language settings if needed
    return $success;
}
 /**
  * Generate the HTML content of this block.
  *
  * @param int      $block_id
  * @param bool     $template
  * @param string[] $cfg
  *
  * @return string
  */
 public function getBlock($block_id, $template = true, $cfg = array())
 {
     global $ctype, $WT_TREE;
     $sendmail = $this->getBlockSetting($block_id, 'sendmail', '1');
     $days = $this->getBlockSetting($block_id, 'days', '1');
     $block = $this->getBlockSetting($block_id, 'block', '1');
     foreach (array('days', 'sendmail', 'block') as $name) {
         if (array_key_exists($name, $cfg)) {
             ${$name} = $cfg[$name];
         }
     }
     $changes = Database::prepare("SELECT 1" . " FROM `##change`" . " WHERE status='pending'" . " LIMIT 1")->fetchOne();
     if ($changes === '1' && $sendmail === '1') {
         // There are pending changes - tell moderators/managers/administrators about them.
         if (WT_TIMESTAMP - Site::getPreference('LAST_CHANGE_EMAIL') > 60 * 60 * 24 * $days) {
             // Which users have pending changes?
             foreach (User::all() as $user) {
                 if ($user->getPreference('contactmethod') !== 'none') {
                     foreach (Tree::getAll() as $tree) {
                         if ($tree->hasPendingEdit() && Auth::isManager($tree, $user)) {
                             I18N::init($user->getPreference('language'));
                             Mail::systemMessage($tree, $user, I18N::translate('Pending changes'), I18N::translate('There are pending changes for you to moderate.') . Mail::EOL . Mail::EOL . '<a href="' . WT_BASE_URL . 'index.php?ged=' . $WT_TREE->getNameUrl() . '">' . WT_BASE_URL . 'index.php?ged=' . $WT_TREE->getNameUrl() . '</a>');
                             I18N::init(WT_LOCALE);
                         }
                     }
                 }
             }
             Site::setPreference('LAST_CHANGE_EMAIL', WT_TIMESTAMP);
         }
     }
     if (Auth::isEditor($WT_TREE) && $WT_TREE->hasPendingEdit()) {
         $id = $this->getName() . $block_id;
         $class = $this->getName() . '_block';
         if ($ctype === 'user' || Auth::isManager($WT_TREE)) {
             $title = '<a class="icon-admin" title="' . I18N::translate('Configure') . '" href="block_edit.php?block_id=' . $block_id . '&amp;ged=' . $WT_TREE->getNameHtml() . '&amp;ctype=' . $ctype . '"></a>';
         } else {
             $title = '';
         }
         $title .= $this->getTitle();
         $content = '';
         if (Auth::isModerator($WT_TREE)) {
             $content .= "<a href=\"#\" onclick=\"window.open('edit_changes.php','_blank', chan_window_specs); return false;\">" . I18N::translate('There are pending changes for you to moderate.') . "</a><br>";
         }
         if ($sendmail === '1') {
             $content .= I18N::translate('Last email reminder was sent ') . FunctionsDate::formatTimestamp(Site::getPreference('LAST_CHANGE_EMAIL')) . "<br>";
             $content .= I18N::translate('Next email reminder will be sent after ') . FunctionsDate::formatTimestamp(Site::getPreference('LAST_CHANGE_EMAIL') + 60 * 60 * 24 * $days) . "<br><br>";
         }
         $content .= '<ul>';
         $changes = Database::prepare("SELECT xref" . " FROM  `##change`" . " WHERE status='pending'" . " AND   gedcom_id=?" . " GROUP BY xref")->execute(array($WT_TREE->getTreeId()))->fetchAll();
         foreach ($changes as $change) {
             $record = GedcomRecord::getInstance($change->xref, $WT_TREE);
             if ($record->canShow()) {
                 $content .= '<li><a href="' . $record->getHtmlUrl() . '">' . $record->getFullName() . '</a></li>';
             }
         }
         $content .= '</ul>';
         if ($template) {
             if ($block) {
                 $class .= ' small_inner_block';
             }
             return Theme::theme()->formatBlock($id, $title, $class, $content);
         } else {
             return $content;
         }
     }
 }
 /**
  * {@inheritDoc}
  * @see \MyArtJaub\Webtrees\Module\AdminTasks\Model\AbstractTask::executeSteps()
  */
 protected function executeSteps()
 {
     $res = false;
     // Get the number of days to take into account, either last 7 days or since last check
     $interval_sincelast = 0;
     if ($this->last_updated) {
         $tmpInt = $this->last_updated->diff(new \DateTime('now'), true);
         $interval_sincelast = ($tmpInt->days * 24 + $tmpInt->h) * 60 + $tmpInt->i;
     }
     $interval = max($this->frequency, $interval_sincelast);
     $nbdays = ceil($interval / (24 * 60));
     // Check for updates
     $latest_version_txt = Functions::fetchLatestVersion();
     if (preg_match('/^[0-9.]+\\|[0-9.]+\\|/', $latest_version_txt)) {
         list($latest_version, , $download_url) = explode('|', $latest_version_txt);
     } else {
         // Cannot determine the latest version
         list($latest_version, , $download_url) = explode('|', '||');
     }
     // Users statistics
     $warnusers = 0;
     $nverusers = 0;
     $applusers = 0;
     foreach (User::all() as $user) {
         if (date("U") - (int) $user->getPreference('reg_timestamp') > 604800 && !$user->getPreference('verified')) {
             $warnusers++;
         }
         if (!$user->getPreference('verified_by_admin') && $user->getPreference('verified')) {
             $nverusers++;
         }
         if (!$user->getPreference('verified')) {
             $applusers++;
         }
     }
     // Tree specifics checks
     $one_tree_done = false;
     foreach (Tree::getAll() as $tree) {
         $isTreeEnabled = $tree->getPreference('MAJ_AT_' . $this->getName() . '_ENABLED');
         if ((is_null($isTreeEnabled) || $isTreeEnabled) && ($webmaster = User::find($tree->getPreference('WEBMASTER_USER_ID')))) {
             I18N::init($webmaster->getPreference('language'));
             $subject = I18N::translate('Health Check Report') . ' - ' . I18N::translate('Tree %s', $tree->getTitle());
             $message = I18N::translate('Health Check Report for the last %d days', $nbdays) . Mail::EOL . Mail::EOL . I18N::translate('Tree %s', $tree->getTitle()) . Mail::EOL . '==========================================' . Mail::EOL . Mail::EOL;
             // News
             $message_version = '';
             if ($latest_version && version_compare(WT_VERSION, $latest_version) < 0) {
                 $message_version = I18N::translate('News') . Mail::EOL . '-------------' . Mail::EOL . I18N::translate('A new version of *webtrees* is available: %s. Upgrade as soon as possible.', $latest_version) . Mail::EOL . I18N::translate('Download it here: %s.', $download_url) . Mail::EOL . Mail::EOL;
             }
             $message .= $message_version;
             // Statistics users
             $message_users = I18N::translate('Users') . Mail::EOL . '-------------' . Mail::EOL . WT_BASE_URL . 'admin_users.php' . Mail::EOL . I18N::translate('Total number of users') . "\t\t" . User::count() . Mail::EOL . I18N::translate('Not verified by the user') . "\t\t" . $applusers . Mail::EOL . I18N::translate('Not approved by an administrator') . "\t" . $nverusers . Mail::EOL . Mail::EOL;
             $message .= $message_users;
             // Statistics tree:
             $stats = new Stats($tree);
             $sql = 'SELECT ged_type AS type, COUNT(change_id) AS chgcount FROM wt_change' . ' JOIN (' . ' SELECT "indi" AS ged_type, i_id AS ged_id, i_file AS ged_file FROM wt_individuals' . ' UNION SELECT "fam" AS ged_type, f_id AS ged_id, f_file AS ged_file FROM wt_families' . ' UNION SELECT "sour" AS ged_type, s_id AS ged_id, s_file AS ged_file FROM wt_sources' . ' UNION SELECT "media" AS ged_type, m_id AS ged_id, m_file AS ged_file FROM wt_media' . ' UNION SELECT LOWER(o_type) AS ged_type, o_id AS ged_id, o_file AS ged_file FROM wt_other' . ') AS gedrecords ON (xref = ged_id AND gedcom_id = ged_file)' . ' WHERE change_time >= DATE_ADD( NOW(), INTERVAL - :nb_days DAY)' . ' AND status = :status AND gedcom_id = :gedcom_id' . ' GROUP BY ged_type';
             $changes = Database::prepare($sql)->execute(array('status' => 'accepted', 'gedcom_id' => $tree->getTreeId(), 'nb_days' => $nbdays))->fetchAssoc();
             $message_gedcom = I18N::translate('Tree statistics') . Mail::EOL . '-------------' . Mail::EOL . sprintf('%-25s', I18N::translate('Records')) . "\t" . sprintf('%15s', I18N::translate('Count')) . "\t" . sprintf('%15s', I18N::translate('Changes')) . Mail::EOL . sprintf('%-25s', I18N::translate('Individuals')) . "\t" . sprintf('%15s', $stats->totalIndividuals()) . "\t" . sprintf('%15s', isset($changes['indi']) ? $changes['indi'] : 0) . Mail::EOL . sprintf('%-25s', I18N::translate('Families')) . "\t" . sprintf('%15s', $stats->totalFamilies()) . "\t" . sprintf('%15s', isset($changes['fam']) ? $changes['fam'] : 0) . Mail::EOL . sprintf('%-25s', I18N::translate('Sources')) . "\t" . sprintf('%15s', $stats->totalSources()) . "\t" . sprintf('%15s', isset($changes['sour']) ? $changes['sour'] : 0) . Mail::EOL . sprintf('%-25s', I18N::translate('Repositories')) . "\t" . sprintf('%15s', $stats->totalRepositories()) . "\t" . sprintf('%15s', isset($changes['repo']) ? $changes['repo'] : 0) . Mail::EOL . sprintf('%-25s', I18N::translate('Media objects')) . "\t" . sprintf('%15s', $stats->totalMedia()) . "\t" . sprintf('%15s', isset($changes['media']) ? $changes['media'] : 0) . Mail::EOL . sprintf('%-25s', I18N::translate('Notes')) . "\t" . sprintf('%15s', $stats->totalNotes()) . "\t" . sprintf('%15s', isset($changes['note']) ? $changes['note'] : 0) . Mail::EOL . Mail::EOL;
             $message .= $message_gedcom;
             //Errors
             $sql = 'SELECT SQL_CACHE log_message, gedcom_id, COUNT(log_id) as nblogs, MAX(log_time) as lastoccurred' . ' FROM `##log`' . ' WHERE log_type = :log_type AND (gedcom_id = :gedcom_id OR ISNULL(gedcom_id))' . ' AND log_time >= DATE_ADD( NOW(), INTERVAL - :nb_days DAY)' . ' GROUP BY log_message, gedcom_id' . ' ORDER BY lastoccurred DESC';
             $errors = Database::prepare($sql)->execute(array('log_type' => Log::TYPE_ERROR, 'gedcom_id' => $tree->getTreeId(), 'nb_days' => $nbdays))->fetchAll();
             $nb_errors = 0;
             $tmp_message = '';
             $nb_char_count_title = strlen(I18N::translate('Count'));
             $nb_char_type = max(strlen(I18N::translate('Type')), strlen(I18N::translate('Site')), strlen(I18N::translate('Tree')));
             foreach ($errors as $error) {
                 $tmp_message .= sprintf('%' . $nb_char_count_title . 'd', $error->nblogs) . "\t";
                 $tmp_message .= sprintf('%' . $nb_char_type . 's', is_null($error->gedcom_id) ? I18N::translate('Site') : I18N::translate('Tree'));
                 $tmp_message .= "\t" . sprintf('%20s', $error->lastoccurred) . "\t";
                 $tmp_message .= str_replace("\n", "\n\t\t\t\t\t\t", $error->log_message) . Mail::EOL;
                 $nb_errors += $error->nblogs;
             }
             if ($nb_errors > 0) {
                 $message .= I18N::translate('Errors [%d]', $nb_errors) . Mail::EOL . '-------------' . Mail::EOL . WT_BASE_URL . 'admin_site_logs.php' . Mail::EOL . I18N::translate('Count') . "\t" . sprintf('%-' . $nb_char_type . 's', I18N::translate('Type')) . "\t" . sprintf('%-20s', I18N::translate('Last occurrence')) . "\t" . I18N::translate('Error') . Mail::EOL . str_repeat('-', $nb_char_count_title) . "\t" . str_repeat('-', $nb_char_type) . "\t" . str_repeat('-', 20) . "\t" . str_repeat('-', strlen(I18N::translate('Error'))) . Mail::EOL . $tmp_message . Mail::EOL;
             } else {
                 $message .= I18N::translate('No errors', $nb_errors) . Mail::EOL . Mail::EOL;
             }
             $tmpres = true;
             if ($webmaster->getPreference('contactmethod') !== 'messaging' && $webmaster->getPreference('contactmethod') !== 'none') {
                 $tmpres = Mail::systemMessage($tree, $webmaster, $subject, $message);
             }
             $res = $tmpres && (!$one_tree_done || $one_tree_done && $res);
             $one_tree_done = true;
         }
     }
     return $res;
 }