public function pageBody()
    {
        $tmp_dir = WT_DATA_DIR . 'ftv_pdf_tmp/';
        define('_JPGRAPH_PATH', $tmp_dir);
        define('_MPDF_TEMP_PATH', $tmp_dir);
        define('_MPDF_TTFONTDATAPATH', $tmp_dir);
        require_once WT_MODULES_DIR . $this->getName() . '/mpdf/mpdf.php';
        $stylesheet = file_get_contents($this->directory . '/css/style.css');
        $stylesheet_rtl = file_get_contents($this->directory . '/css/style-rtl.css');
        $html = Filter::post('pdfContent');
        $header = '<header>=== ' . $this->tree()->getTitleHtml() . ' ===</header>';
        $footer = '<footer>' . '<table><tr>' . '<td class="left">' . WT_BASE_URL . '</td>' . '<td class="center">{DATE d-m-Y}</td>' . '<td class="right">{PAGENO}</td>' . '</tr></table>' . '</footer>';
        $mpdf = new mPDF();
        $mpdf->simpleTables = true;
        $mpdf->shrink_tables_to_fit = 1;
        $mpdf->autoScriptToLang = true;
        $mpdf->baseScript = 1;
        $mpdf->autoVietnamese = true;
        $mpdf->autoArabic = true;
        $mpdf->autoLangToFont = true;
        if (I18N::direction() === 'rtl') {
            $mpdf->SetDirectionality('rtl');
            $mpdf->WriteHTML($stylesheet_rtl, 1);
        } else {
            $mpdf->WriteHTML($stylesheet, 1);
        }
        $mpdf->setAutoTopMargin = 'stretch';
        $mpdf->setAutoBottomMargin = 'stretch';
        $mpdf->autoMarginPadding = 5;
        $admin = User::find($this->tree()->getPreference('WEBMASTER_USER_ID'))->getRealName();
        $mpdf->setCreator($this->getTitle() . ' - a webtrees module by justcarmen.nl');
        $mpdf->SetTitle(Filter::get('title'));
        $mpdf->setAuthor($admin);
        $mpdf->SetHTMLHeader($header);
        $mpdf->setHTMLFooter($footer);
        $html_chunks = explode("\n", $html);
        $chunks = count($html_chunks);
        $i = 1;
        foreach ($html_chunks as $html_chunk) {
            // write html body parts only (option 2);
            if ($i === 1) {
                // first chunk (initialize all buffers - init=true)
                $mpdf->WriteHTML($html_chunk, 2, true, false);
            } elseif ($i === $chunks) {
                // last chunck (close all buffers - close=true)
                $mpdf->WriteHTML($html_chunk, 2, false, true);
            } else {
                // all other parts (keep the buffer open)
                $mpdf->WriteHTML($html_chunk, 2, false, false);
            }
            $i++;
        }
        $index = '
				<pagebreak type="next-odd" />
				<h2>' . I18N::translate('Index') . '</h2>
				<columns column-count="2" column-gap="5" />
				<indexinsert usedivletters="on" links="on" collation="' . WT_LOCALE . '.utf8" collationgroup="' . I18N::collation() . '" />';
        $mpdf->writeHTML($index);
        $mpdf->Output($tmp_dir . Filter::get('title') . '.pdf', 'F');
    }
示例#2
0
    public function pageBody()
    {
        $cache_dir = WT_DATA_DIR . 'ftv_cache/';
        define("_JPGRAPH_PATH", $cache_dir);
        define("_MPDF_TEMP_PATH", $cache_dir);
        define('_MPDF_TTFONTDATAPATH', $cache_dir);
        require_once WT_MODULES_DIR . $this->getName() . '/packages/mpdf60/mpdf.php';
        $tmpfile = $cache_dir . 'fancy-treeview-tmp.txt';
        if (file_exists($cache_dir) && is_readable($tmpfile)) {
            $stylesheet = file_get_contents($this->directory . '/css/pdf/style.css');
            $stylesheet_rtl = file_get_contents($this->directory . '/css/pdf/style-rtl.css');
            $html = file_get_contents($tmpfile);
            $header = '<header>=== ' . $this->tree->getTitleHtml() . ' ===</header>';
            $footer = '<footer>' . '<table><tr>' . '<td class="left">' . WT_BASE_URL . '</td>' . '<td class="center">{DATE d-m-Y}</td>' . '<td class="right">{PAGENO}</td>' . '</tr></table>' . '</footer>';
            $mpdf = new mPDF();
            $mpdf->simpleTables = true;
            $mpdf->shrink_tables_to_fit = 1;
            $mpdf->autoScriptToLang = true;
            if (I18N::direction() === 'rtl') {
                $mpdf->SetDirectionality('rtl');
            }
            if (I18N::direction() === 'rtl') {
                $mpdf->WriteHTML($stylesheet_rtl, 1);
            } else {
                $mpdf->WriteHTML($stylesheet, 1);
            }
            $mpdf->setAutoTopMargin = 'stretch';
            $mpdf->setAutoBottomMargin = 'stretch';
            $mpdf->autoMarginPadding = 5;
            $admin = User::find($this->tree->getPreference('WEBMASTER_USER_ID'))->getRealName();
            $mpdf->setCreator($this->getTitle() . ' - a webtrees module by justcarmen.nl');
            $mpdf->SetTitle(Filter::get('title'));
            $mpdf->setAuthor($admin);
            $mpdf->SetHTMLHeader($header);
            $mpdf->setHTMLFooter($footer);
            $html_chunks = explode("\n", $html);
            $chunks = count($html_chunks);
            $i = 1;
            foreach ($html_chunks as $html_chunk) {
                if ($i === 1) {
                    $mpdf->WriteHTML($html_chunk, 2, true, false);
                } elseif ($i === $chunks) {
                    $mpdf->WriteHTML($html_chunk, 2, false, false);
                } else {
                    $mpdf->WriteHTML($html_chunk, 2, false, true);
                }
                $i++;
            }
            $index = '
				<pagebreak type="next-odd" />
				<h2>' . I18N::translate('Index') . '</h2>
				<columns column-count="2" column-gap="5" />
				<indexinsert usedivletters="on" links="on" collation="' . WT_LOCALE . '.utf8" collationgroup="' . I18N::collation() . '" />';
            $mpdf->writeHTML($index);
            $mpdf->Output(Filter::get('title') . '.pdf', 'D');
        } else {
            echo $this->addMessage('alert', 'danger', false, I18N::translate('Error: the pdf file could not be generated.'));
        }
    }
示例#3
0
 /**
  * Return a computed array of statistics about the dispersion of ancestors across the ancestors
  * at a specified generation.
  * This statistics cannot be used for generations above 11, as it would cause a out of range in MySQL
  * 
  * Format: 
  *  - key : a base-2 representation of the ancestor at generation G for which exclusive ancestors have been found,
  *          -1 is used for shared ancestors
  *          For instance base2(0100) = base10(4) represent the maternal grand father
  *  - values: number of ancestors exclusively in the ancestors of the ancestor in key
  *  
  *  For instance a result at generation 3 could be :
  *      array (   -1        =>  12      -> 12 ancestors are shared by the grand-parents
  *                base10(1) =>  32      -> 32 ancestors are exclusive to the paternal grand-father
  *                base10(2) =>  25      -> 25 ancestors are exclusive to the paternal grand-mother
  *                base10(4) =>  12      -> 12 ancestors are exclusive to the maternal grand-father
  *                base10(8) =>  30      -> 30 ancestors are exclusive to the maternal grand-mother
  *            )
  *  
  * @param int $gen Reference generation
  * @return array
  */
 public function getAncestorDispersionForGen($gen)
 {
     if (!$this->is_setup || $gen > 11) {
         return array();
     }
     // Going further than 11 gen will be out of range in the query
     return Database::prepare('SELECT branches, count(i_id)' . ' FROM (' . '   SELECT i_id,' . '       CASE' . '           WHEN CEIL(LOG2(SUM(branch))) = LOG2(SUM(branch)) THEN SUM(branch)' . '           ELSE -1' . '       END branches' . '   FROM (' . '       SELECT DISTINCT majs_i_id i_id,' . '           POW(2, FLOOR(majs_sosa / POW(2, (majs_gen - :gen))) - POW(2, :gen -1)) branch' . '       FROM `##maj_sosa`' . '       WHERE majs_gedcom_id = :tree_id AND majs_user_id = :user_id' . '           AND majs_gen >= :gen' . '   ) indistat' . '   GROUP BY i_id' . ') grouped' . ' GROUP BY branches')->execute(array('tree_id' => $this->tree->getTreeId(), 'user_id' => $this->user->getUserId(), 'gen' => $gen))->fetchAssoc() ?: array();
 }
示例#4
0
 /**
  * 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 $WT_TREE;
     $id = $this->getName() . $block_id;
     $class = $this->getName() . '_block';
     $title = $this->getTitle();
     $anonymous = 0;
     $logged_in = array();
     $content = '';
     foreach (User::allLoggedIn() as $user) {
         if (Auth::isAdmin() || $user->getPreference('visibleonline')) {
             $logged_in[] = $user;
         } else {
             $anonymous++;
         }
     }
     $count_logged_in = count($logged_in);
     $content .= '<div class="logged_in_count">';
     if ($anonymous) {
         $content .= I18N::plural('%s anonymous signed-in user', '%s anonymous signed-in users', $anonymous, I18N::number($anonymous));
         if ($count_logged_in) {
             $content .= '&nbsp;|&nbsp;';
         }
     }
     if ($count_logged_in) {
         $content .= I18N::plural('%s signed-in user', '%s signed-in users', $count_logged_in, I18N::number($count_logged_in));
     }
     $content .= '</div>';
     $content .= '<div class="logged_in_list">';
     if (Auth::check()) {
         foreach ($logged_in as $user) {
             $individual = Individual::getInstance($WT_TREE->getUserPreference($user, 'gedcomid'), $WT_TREE);
             $content .= '<div class="logged_in_name">';
             if ($individual) {
                 $content .= '<a href="' . $individual->getHtmlUrl() . '">' . $user->getRealNameHtml() . '</a>';
             } else {
                 $content .= $user->getRealNameHtml();
             }
             $content .= ' - ' . Filter::escapeHtml($user->getUserName());
             if (Auth::id() != $user->getUserId() && $user->getPreference('contactmethod') != 'none') {
                 $content .= ' <a class="icon-email" href="#" onclick="return message(\'' . Filter::escapeHtml($user->getUserName()) . '\', \'\', \'' . Filter::escapeHtml(Functions::getQueryUrl()) . '\');" title="' . I18N::translate('Send a message') . '"></a>';
             }
             $content .= '</div>';
         }
     }
     $content .= '</div>';
     if ($anonymous === 0 && $count_logged_in === 0) {
         return '';
     }
     if ($template) {
         return Theme::theme()->formatBlock($id, $title, $class, $content);
     } else {
         return $content;
     }
 }
 /**
  * {@inheritDoc}
  * @see \MyArtJaub\Webtrees\Hook\HookInterfaces\PageFooterExtenderInterface::hPrintFooter()
  */
 public function hPrintFooter()
 {
     global $WT_TREE;
     $html = '';
     if ($this->getSetting('MAJ_DISPLAY_CNIL', 0) == 1) {
         $html .= '<br/>';
         $html .= '<div class="center">';
         $cnil_ref = $this->getSetting('MAJ_CNIL_REFERENCE', '');
         if ($cnil_ref != '') {
             $html .= I18N::translate('This site has been notified to the French National Commission for Data protection (CNIL) and registered under number %s. ', $cnil_ref);
         }
         $html .= I18N::translate('In accordance with the French Data protection Act (<em>Loi Informatique et Libertés</em>) of January 6th, 1978, you have the right to access, modify, rectify and delete personal information that pertains to you. To exercice this right, please contact %s, and provide your name, address and a proof of your identity.', Theme::theme()->contactLink(User::find($WT_TREE->getPreference('WEBMASTER_USER_ID'))));
         $html .= '</div>';
     }
     if ($this->getSetting('MAJ_ADD_HTML_FOOTER', 0) == 1) {
         if (Auth::accessLevel($WT_TREE) >= $this->getSetting('MAJ_SHOW_HTML_FOOTER', Auth::PRIV_HIDE) && !Filter::getBool('nofooter')) {
             $html .= $this->getSetting('MAJ_HTML_FOOTER', '');
         }
     }
     return $html;
 }
 /**
  * print information for a name record
  *
  * @param Fact $event the event object
  */
 public function printNameRecord(Fact $event)
 {
     $factrec = $event->getGedcom();
     // Create a dummy record, so we can extract the formatted NAME value from the event.
     $dummy = new Individual('xref', "0 @xref@ INDI\n1 DEAT Y\n" . $factrec, null, $event->getParent()->getTree());
     $all_names = $dummy->getAllNames();
     $primary_name = $all_names[0];
     $this->name_count++;
     if ($this->name_count > 1) {
         echo '<h3 class="name_two">', $dummy->getFullName(), '</h3>';
     }
     //Other names accordion element
     echo '<div class="indi_name_details';
     if ($event->isPendingDeletion()) {
         echo ' old';
     }
     if ($event->isPendingAddition()) {
         echo ' new';
     }
     echo '">';
     echo '<div class="name1">';
     echo '<dl><dt class="label">', I18N::translate('Name'), '</dt>';
     $dummy->setPrimaryName(0);
     echo '<dd class="field">', $dummy->getFullName();
     if ($this->name_count == 1) {
         if (Auth::isAdmin()) {
             $user = User::findByGenealogyRecord($this->record);
             if ($user) {
                 echo '<span> - <a class="warning" href="admin_users.php?filter=' . Filter::escapeHtml($user->getUserName()) . '">' . Filter::escapeHtml($user->getUserName()) . '</a></span>';
             }
         }
     }
     if ($this->record->canEdit() && !$event->isPendingDeletion()) {
         echo "<div class=\"deletelink\"><a class=\"deleteicon\" href=\"#\" onclick=\"return delete_fact('" . I18N::translate('Are you sure you want to delete this fact?') . "', '" . $this->record->getXref() . "', '" . $event->getFactId() . "');\" title=\"" . I18N::translate('Delete this name') . "\"><span class=\"link_text\">" . I18N::translate('Delete this name') . "</span></a></div>";
         echo "<div class=\"editlink\"><a href=\"#\" class=\"editicon\" onclick=\"edit_name('" . $this->record->getXref() . "', '" . $event->getFactId() . "'); return false;\" title=\"" . I18N::translate('Edit name') . "\"><span class=\"link_text\">" . I18N::translate('Edit name') . "</span></a></div>";
     }
     echo '</dd>';
     echo '</dl>';
     echo '</div>';
     $ct = preg_match_all('/\\n2 (\\w+) (.*)/', $factrec, $nmatch, PREG_SET_ORDER);
     for ($i = 0; $i < $ct; $i++) {
         echo '<div>';
         $fact = $nmatch[$i][1];
         if ($fact != 'SOUR' && $fact != 'NOTE' && $fact != 'SPFX') {
             echo '<dl><dt class="label">', GedcomTag::getLabel($fact, $this->record), '</dt>';
             echo '<dd class="field">';
             // Before using dir="auto" on this field, note that Gecko treats this as an inline element but WebKit treats it as a block element
             if (isset($nmatch[$i][2])) {
                 $name = Filter::escapeHtml($nmatch[$i][2]);
                 $name = str_replace('/', '', $name);
                 $name = preg_replace('/(\\S*)\\*/', '<span class="starredname">\\1</span>', $name);
                 switch ($fact) {
                     case 'TYPE':
                         echo GedcomCodeName::getValue($name, $this->record);
                         break;
                     case 'SURN':
                         // The SURN field is not necessarily the surname.
                         // Where it is not a substring of the real surname, show it after the real surname.
                         $surname = Filter::escapeHtml($primary_name['surname']);
                         if (strpos($primary_name['surname'], str_replace(',', ' ', $nmatch[$i][2])) !== false) {
                             echo '<span dir="auto">' . $surname . '</span>';
                         } else {
                             echo I18N::translate('%1$s (%2$s)', '<span dir="auto">' . $surname . '</span>', '<span dir="auto">' . $name . '</span>');
                         }
                         break;
                     default:
                         echo '<span dir="auto">' . $name . '</span>';
                         break;
                 }
             }
             echo '</dd>';
             echo '</dl>';
         }
         echo '</div>';
     }
     if (preg_match("/\n2 SOUR/", $factrec)) {
         echo '<div id="indi_sour" class="clearfloat">', FunctionsPrintFacts::printFactSources($factrec, 2), '</div>';
     }
     if (preg_match("/\n2 NOTE/", $factrec)) {
         echo '<div id="indi_note" class="clearfloat">', FunctionsPrint::printFactNotes($factrec, 2), '</div>';
     }
     echo '</div>';
 }
示例#7
0
			locale: "' . WT_LOCALE . '",
			icons: {
				time: "fa fa-clock-o",
				date: "fa fa-calendar",
				up: "fa fa-arrow-up",
				down: "fa fa-arrow-down",
				previous: "fa fa-arrow-' . (I18N::direction() === 'rtl' ? 'right' : 'left') . '",
				next: "fa fa-arrow-' . (I18N::direction() === 'rtl' ? 'left' : 'right') . '",
				today: "fa fa-trash-o",
				clear: "fa fa-trash-o"
			}
		});
	');
$url = WT_SCRIPT_NAME . '?from=' . rawurlencode($from) . '&amp;to=' . rawurlencode($to) . '&amp;type=' . rawurlencode($type) . '&amp;oldged=' . rawurlencode($oldged) . '&amp;newged=' . rawurlencode($newged) . '&amp;xref=' . rawurlencode($xref) . '&amp;user='******'&amp;gedc=' . rawurlencode($gedc);
$users_array = array();
foreach (User::all() as $tmp_user) {
    $users_array[$tmp_user->getUserName()] = $tmp_user->getUserName();
}
?>
<ol class="breadcrumb small">
	<li><a href="admin.php"><?php 
echo I18N::translate('Control panel');
?>
</a></li>
	<li><a href="admin_trees_manage.php"><?php 
echo I18N::translate('Manage family trees');
?>
</a></li>
	<li class="active"><?php 
echo $controller->getPageTitle();
?>
示例#8
0
								<?php 
    echo I18N::translate('After creating the family tree, you will be able to import data from a GEDCOM file.');
    ?>
							</p>
						</div>
					</div>
				</form>
			</div>
		</div>
	</div>
	<?php 
}
?>
	<!-- display link to PhpGedView-WT transfer wizard on first visit to this page, before any GEDCOM is loaded -->
	<?php 
if (count(Tree::GetAll()) === 0 && count(User::all()) === 1) {
    ?>
	<div class="panel panel-default">
		<div class="panel-heading">
			<h2 class="panel-title">
			<i class="fa fa-fw fa-magic"></i>
			<a data-toggle="collapse" data-parent="#accordion" href="#pgv-import-wizard">
				<?php 
    echo I18N::translate('PhpGedView to webtrees transfer wizard');
    ?>
			</a>
		</h2>
		</div>
		<div id="pgv-import-wizard" class="panel-collapse collapse">
			<div class="panel-body">
				<p>
示例#9
0
 /**
  * Get the tree’s user-configuration settings.
  *
  * @param User        $user
  * @param string      $setting_name
  * @param string|null $default
  *
  * @return string
  */
 public function getUserPreference(User $user, $setting_name, $default = null)
 {
     // There are lots of settings, and we need to fetch lots of them on every page
     // so it is quicker to fetch them all in one go.
     if (!array_key_exists($user->getUserId(), $this->user_preferences)) {
         $this->user_preferences[$user->getUserId()] = Database::prepare("SELECT SQL_CACHE setting_name, setting_value FROM `##user_gedcom_setting` WHERE user_id = ? AND gedcom_id = ?")->execute(array($user->getUserId(), $this->tree_id))->fetchAssoc();
     }
     if (array_key_exists($setting_name, $this->user_preferences[$user->getUserId()])) {
         return $this->user_preferences[$user->getUserId()][$setting_name];
     } else {
         return $default;
     }
 }
示例#10
0
        $files_to_delete[] = $file;
    }
}
$controller = new PageController();
$controller->restrictAccess(Auth::isManager($WT_TREE))->setPageTitle(I18N::translate('Control panel') . ' — ' . I18N::translate('Dashboard'))->pageHeader();
// Check for updates
$latest_version_txt = Functions::fetchLatestVersion();
if (preg_match('/^[0-9.]+\\|[0-9.]+\\|/', $latest_version_txt)) {
    list($latest_version) = explode('|', $latest_version_txt);
} else {
    // Cannot determine the latest version
    $latest_version = '';
}
$update_available = Auth::isAdmin() && $latest_version && version_compare(WT_VERSION, $latest_version) < 0;
// Total number of users
$total_users = User::count();
// Administrators
$administrators = Database::prepare("SELECT SQL_CACHE user_id, real_name FROM `##user` JOIN `##user_setting` USING (user_id) WHERE setting_name='canadmin' AND setting_value='1'")->fetchAll();
// Managers
$managers = Database::prepare("SELECT SQL_CACHE user_id, real_name FROM `##user` JOIN `##user_gedcom_setting` USING (user_id)" . " WHERE setting_name = 'canedit' AND setting_value='admin'" . " GROUP BY user_id, real_name" . " ORDER BY real_name")->fetchAll();
// Moderators
$moderators = Database::prepare("SELECT SQL_CACHE user_id, real_name FROM `##user` JOIN `##user_gedcom_setting` USING (user_id)" . " WHERE setting_name = 'canedit' AND setting_value='accept'" . " GROUP BY user_id, real_name" . " ORDER BY real_name")->fetchAll();
// Number of users who have not verified their email address
$unverified = Database::prepare("SELECT SQL_CACHE user_id, real_name FROM `##user` JOIN `##user_setting` USING (user_id)" . " WHERE setting_name = 'verified' AND setting_value = '0'" . " ORDER BY real_name")->fetchAll();
// Number of users whose accounts are not approved by an administrator
$unapproved = Database::prepare("SELECT SQL_CACHE user_id, real_name FROM `##user` JOIN `##user_setting` USING (user_id)" . " WHERE setting_name = 'verified_by_admin' AND setting_value = '0'" . " ORDER BY real_name")->fetchAll();
// Users currently logged in
$logged_in = Database::prepare("SELECT SQL_NO_CACHE DISTINCT user_id, real_name FROM `##user` JOIN `##session` USING (user_id)" . " ORDER BY real_name")->fetchAll();
// Count of records
$individuals = Database::prepare("SELECT SQL_CACHE gedcom_id, COUNT(i_id) AS count FROM `##gedcom` LEFT JOIN `##individuals` ON gedcom_id = i_file GROUP BY gedcom_id")->fetchAssoc();
$families = Database::prepare("SELECT SQL_CACHE gedcom_id, COUNT(f_id) AS count FROM `##gedcom` LEFT JOIN `##families` ON gedcom_id = f_file GROUP BY gedcom_id")->fetchAssoc();
示例#11
0
文件: login.php 项目: ambled/webtrees
			</div>
			<div>
				<input type="submit" value="', I18N::translate('Send'), '">
			</div>
		</form>
	</div>';
        break;
    case 'verify_hash':
        if (!Site::getPreference('USE_REGISTRATION_MODULE')) {
            header('Location: ' . WT_BASE_URL);
            return;
        }
        // switch language to webmaster settings
        $webmaster = User::find($WT_TREE->getPreference('WEBMASTER_USER_ID'));
        I18N::init($webmaster->getPreference('language'));
        $user = User::findByIdentifier($user_name);
        $mail1_body = I18N::translate('Hello administrator…') . Mail::EOL . Mail::EOL . I18N::translate('A new user (%1$s) has requested an account (%2$s) and verified an email address (%3$s).', $user->getRealNameHtml(), Filter::escapeHtml($user->getUserName()), Filter::escapeHtml($user->getEmail())) . Mail::EOL . Mail::EOL . I18N::translate('You now need to review the account details, and set the “approved” status to “yes”.') . Mail::EOL . '<a href="' . WT_BASE_URL . "admin_users.php?filter=" . Filter::escapeUrl($user->getUserName()) . '">' . WT_BASE_URL . "admin_users.php?filter=" . Filter::escapeUrl($user->getUserName()) . '</a>' . Mail::auditFooter();
        $mail1_subject = I18N::translate('New user at %s', WT_BASE_URL . ' ' . $WT_TREE->getTitle());
        // Change to the new user’s language
        I18N::init($user->getPreference('language'));
        $controller->setPageTitle(I18N::translate('User verification'));
        $controller->pageHeader();
        echo '<div id="login-register-page">';
        echo '<h2>' . I18N::translate('User verification') . '</h2>';
        echo '<div id="user-verify">';
        if ($user && $user->checkPassword($user_password) && $user->getPreference('reg_hashcode') === $user_hashcode) {
            Mail::send($WT_TREE, $webmaster->getEmail(), $webmaster->getRealName(), $WT_TREE->getPreference('WEBTREES_EMAIL'), $WT_TREE->getPreference('WEBTREES_EMAIL'), $mail1_subject, $mail1_body);
            $mail1_method = $webmaster->getPreference('CONTACT_METHOD');
            if ($mail1_method != 'messaging3' && $mail1_method != 'mailto' && $mail1_method != 'none') {
                Database::prepare("INSERT INTO `##message` (sender, ip_address, user_id, subject, body) VALUES (? ,? ,? ,? ,?)")->execute(array($user_name, WT_CLIENT_IP, $webmaster->getUserId(), $mail1_subject, Filter::unescapeHtml($mail1_body)));
            }
示例#12
0
 /**
  * Send an automated system message (such as a password reminder) from a tree to a user.
  *
  * @param Tree   $tree
  * @param User   $user
  * @param string $subject
  * @param string $message
  *
  * @return bool
  */
 public static function systemMessage(Tree $tree, User $user, $subject, $message)
 {
     return self::send($tree, $user->getEmail(), $user->getRealName(), Site::getPreference('SMTP_FROM_NAME'), $tree->getPreference('title'), $subject, $message);
 }
示例#13
0
 /**
  * SosaConfig@computePartial
  */
 public function computePartial()
 {
     global $WT_TREE;
     $controller = new AjaxController();
     $controller->restrictAccess($this->canUpdate());
     $view_bag = new ViewBag();
     $view_bag->set('is_success', false);
     $user = User::find(Filter::getInteger('userid', -1));
     $indi = Individual::getInstance(Filter::get('pid', WT_REGEX_XREF), $WT_TREE);
     if ($user && $indi) {
         $calculator = new SosaCalculator($WT_TREE, $user);
         if ($calculator->computeFromIndividual($indi)) {
             $view_bag->set('is_success', true);
         }
     } else {
         $view_bag->set('error', I18N::translate('Non existing individual'));
     }
     ViewFactory::make('SosaComputeResult', $this, $controller, $view_bag)->render();
 }
示例#14
0
    echo '<input type="hidden" name="wtpass2" value="', Filter::escapeHtml($_POST['wtpass2']), '">';
    echo '<input type="hidden" name="wtemail" value="', Filter::escapeHtml($_POST['wtemail']), '">';
}
////////////////////////////////////////////////////////////////////////////////
// Step six  We have a database connection and a writable folder. Do it!
////////////////////////////////////////////////////////////////////////////////
try {
    // Create/update the database tables.
    Database::updateSchema('\\Fisharebest\\Webtrees\\Schema', 'WT_SCHEMA_VERSION', 30);
    // If we are re-installing, then this user may already exist.
    $admin = User::findByIdentifier($_POST['wtemail']);
    if ($admin === null) {
        $admin = User::findByIdentifier($_POST['wtuser']);
    }
    // Create the user
    if ($admin === null) {
        $admin = User::create($_POST['wtuser'], $_POST['wtname'], $_POST['wtemail'], $_POST['wtpass'])->setPreference('language', WT_LOCALE)->setPreference('visibleonline', '1');
    } else {
        $admin->setPassword($_POST['wtpass']);
    }
    // Make the user an administrator
    $admin->setPreference('canadmin', '1')->setPreference('verified', '1')->setPreference('verified_by_admin', '1');
    // Write the config file. We already checked that this would work.
    $config_ini_php = '; <' . '?php exit; ?' . '> DO NOT DELETE THIS LINE' . PHP_EOL . 'dbhost="' . addcslashes($_POST['dbhost'], '"') . '"' . PHP_EOL . 'dbport="' . addcslashes($_POST['dbport'], '"') . '"' . PHP_EOL . 'dbuser="******"') . '"' . PHP_EOL . 'dbpass="******"') . '"' . PHP_EOL . 'dbname="' . addcslashes($_POST['dbname'], '"') . '"' . PHP_EOL . 'tblpfx="' . addcslashes($_POST['tblpfx'], '"') . '"' . PHP_EOL;
    file_put_contents(WT_DATA_DIR . 'config.ini.php', $config_ini_php);
    // Done - start using webtrees!
    echo '<script>document.location=document.location;</script>';
    echo '</form></body></html>';
} catch (PDOException $ex) {
    echo '<p class="bad">', I18N::translate('An unexpected database error occurred.'), '</p>', '<pre>', $ex->getMessage(), '</pre>', '<p class="info">', I18N::translate('The webtrees developers would be very interested to learn about this error. If you contact them, they will help you resolve the problem.'), '</p>';
}
 /**
  * Create the clippings controller
  */
 public function __construct()
 {
     global $WT_TREE;
     // Our cart is an array of items in the session
     $this->cart = Session::get('cart', array());
     if (!array_key_exists($WT_TREE->getTreeId(), $this->cart)) {
         $this->cart[$WT_TREE->getTreeId()] = array();
     }
     $this->action = Filter::get('action');
     $this->id = Filter::get('id');
     $convert = Filter::get('convert', 'yes|no', 'no');
     $this->Zip = Filter::get('Zip');
     $this->IncludeMedia = Filter::get('IncludeMedia');
     $this->conv_path = Filter::get('conv_path');
     $this->privatize_export = Filter::get('privatize_export', 'none|visitor|user|gedadmin', 'visitor');
     $this->level1 = Filter::getInteger('level1');
     $this->level2 = Filter::getInteger('level2');
     $this->level3 = Filter::getInteger('level3');
     $others = Filter::get('others');
     $this->type = Filter::get('type');
     if (($this->privatize_export === 'none' || $this->privatize_export === 'none') && !Auth::isManager($WT_TREE)) {
         $this->privatize_export = 'visitor';
     }
     if ($this->privatize_export === 'user' && !Auth::isMember($WT_TREE)) {
         $this->privatize_export = 'visitor';
     }
     if ($this->action === 'add') {
         if (empty($this->type) && !empty($this->id)) {
             $obj = GedcomRecord::getInstance($this->id, $WT_TREE);
             if ($obj) {
                 $this->type = $obj::RECORD_TYPE;
             } else {
                 $this->type = '';
                 $this->id = '';
                 $this->action = '';
             }
         } elseif (empty($this->id)) {
             $this->action = '';
         }
         if (!empty($this->id) && $this->type !== 'FAM' && $this->type !== 'INDI' && $this->type !== 'SOUR') {
             $this->action = 'add1';
         }
     }
     if ($this->action === 'add1') {
         $obj = GedcomRecord::getInstance($this->id, $WT_TREE);
         $this->addClipping($obj);
         if ($this->type === 'SOUR') {
             if ($others === 'linked') {
                 foreach ($obj->linkedIndividuals('SOUR') as $indi) {
                     $this->addClipping($indi);
                 }
                 foreach ($obj->linkedFamilies('SOUR') as $fam) {
                     $this->addClipping($fam);
                 }
             }
         }
         if ($this->type === 'FAM') {
             if ($others === 'parents') {
                 $this->addClipping($obj->getHusband());
                 $this->addClipping($obj->getWife());
             } elseif ($others === "members") {
                 $this->addFamilyMembers(Family::getInstance($this->id, $WT_TREE));
             } elseif ($others === "descendants") {
                 $this->addFamilyDescendancy(Family::getInstance($this->id, $WT_TREE));
             }
         } elseif ($this->type === 'INDI') {
             if ($others === 'parents') {
                 foreach (Individual::getInstance($this->id, $WT_TREE)->getChildFamilies() as $family) {
                     $this->addFamilyMembers($family);
                 }
             } elseif ($others === 'ancestors') {
                 $this->addAncestorsToCart(Individual::getInstance($this->id, $WT_TREE), $this->level1);
             } elseif ($others === 'ancestorsfamilies') {
                 $this->addAncestorsToCartFamilies(Individual::getInstance($this->id, $WT_TREE), $this->level2);
             } elseif ($others === 'members') {
                 foreach (Individual::getInstance($this->id, $WT_TREE)->getSpouseFamilies() as $family) {
                     $this->addFamilyMembers($family);
                 }
             } elseif ($others === 'descendants') {
                 foreach (Individual::getInstance($this->id, $WT_TREE)->getSpouseFamilies() as $family) {
                     $this->addClipping($family);
                     $this->addFamilyDescendancy($family, $this->level3);
                 }
             }
             uksort($this->cart[$WT_TREE->getTreeId()], array($this, 'compareClippings'));
         }
     } elseif ($this->action === 'remove') {
         unset($this->cart[$WT_TREE->getTreeId()][$this->id]);
     } elseif ($this->action === 'empty') {
         $this->cart[$WT_TREE->getTreeId()] = array();
     } elseif ($this->action === 'download') {
         $media = array();
         $mediacount = 0;
         $filetext = FunctionsExport::gedcomHeader($WT_TREE);
         // Include SUBM/SUBN records, if they exist
         $subn = Database::prepare("SELECT o_gedcom FROM `##other` WHERE o_type=? AND o_file=?")->execute(array('SUBN', $WT_TREE->getTreeId()))->fetchOne();
         if ($subn) {
             $filetext .= $subn . "\n";
         }
         $subm = Database::prepare("SELECT o_gedcom FROM `##other` WHERE o_type=? AND o_file=?")->execute(array('SUBM', $WT_TREE->getTreeId()))->fetchOne();
         if ($subm) {
             $filetext .= $subm . "\n";
         }
         if ($convert === "yes") {
             $filetext = str_replace("UTF-8", "ANSI", $filetext);
             $filetext = utf8_decode($filetext);
         }
         switch ($this->privatize_export) {
             case 'gedadmin':
                 $access_level = Auth::PRIV_NONE;
                 break;
             case 'user':
                 $access_level = Auth::PRIV_USER;
                 break;
             case 'visitor':
                 $access_level = Auth::PRIV_PRIVATE;
                 break;
             case 'none':
                 $access_level = Auth::PRIV_HIDE;
                 break;
         }
         foreach (array_keys($this->cart[$WT_TREE->getTreeId()]) as $xref) {
             $object = GedcomRecord::getInstance($xref, $WT_TREE);
             // The object may have been deleted since we added it to the cart....
             if ($object) {
                 $record = $object->privatizeGedcom($access_level);
                 // Remove links to objects that aren't in the cart
                 preg_match_all('/\\n1 ' . WT_REGEX_TAG . ' @(' . WT_REGEX_XREF . ')@(\\n[2-9].*)*/', $record, $matches, PREG_SET_ORDER);
                 foreach ($matches as $match) {
                     if (!array_key_exists($match[1], $this->cart[$WT_TREE->getTreeId()])) {
                         $record = str_replace($match[0], '', $record);
                     }
                 }
                 preg_match_all('/\\n2 ' . WT_REGEX_TAG . ' @(' . WT_REGEX_XREF . ')@(\\n[3-9].*)*/', $record, $matches, PREG_SET_ORDER);
                 foreach ($matches as $match) {
                     if (!array_key_exists($match[1], $this->cart[$WT_TREE->getTreeId()])) {
                         $record = str_replace($match[0], '', $record);
                     }
                 }
                 preg_match_all('/\\n3 ' . WT_REGEX_TAG . ' @(' . WT_REGEX_XREF . ')@(\\n[4-9].*)*/', $record, $matches, PREG_SET_ORDER);
                 foreach ($matches as $match) {
                     if (!array_key_exists($match[1], $this->cart[$WT_TREE->getTreeId()])) {
                         $record = str_replace($match[0], '', $record);
                     }
                 }
                 $record = FunctionsExport::convertMediaPath($record, $this->conv_path);
                 $savedRecord = $record;
                 // Save this for the "does this file exist" check
                 if ($convert === 'yes') {
                     $record = utf8_decode($record);
                 }
                 switch ($object::RECORD_TYPE) {
                     case 'INDI':
                         $filetext .= $record . "\n";
                         $filetext .= "1 SOUR @WEBTREES@\n";
                         $filetext .= "2 PAGE " . WT_BASE_URL . $object->getRawUrl() . "\n";
                         break;
                     case 'FAM':
                         $filetext .= $record . "\n";
                         $filetext .= "1 SOUR @WEBTREES@\n";
                         $filetext .= "2 PAGE " . WT_BASE_URL . $object->getRawUrl() . "\n";
                         break;
                     case 'SOUR':
                         $filetext .= $record . "\n";
                         $filetext .= "1 NOTE " . WT_BASE_URL . $object->getRawUrl() . "\n";
                         break;
                     default:
                         // This autoloads the PclZip library, so we can use its constants.
                         new PclZip('');
                         $ft = preg_match_all("/\n\\d FILE (.+)/", $savedRecord, $match, PREG_SET_ORDER);
                         $MEDIA_DIRECTORY = $WT_TREE->getPreference('MEDIA_DIRECTORY');
                         for ($k = 0; $k < $ft; $k++) {
                             // Skip external files and non-existant files
                             if (file_exists(WT_DATA_DIR . $MEDIA_DIRECTORY . $match[$k][1])) {
                                 $media[$mediacount] = array(\PCLZIP_ATT_FILE_NAME => WT_DATA_DIR . $MEDIA_DIRECTORY . $match[$k][1], \PCLZIP_ATT_FILE_NEW_FULL_NAME => $match[$k][1]);
                                 $mediacount++;
                             }
                         }
                         $filetext .= trim($record) . "\n";
                         break;
                 }
             }
         }
         if ($this->IncludeMedia === "yes") {
             $this->media_list = $media;
         } else {
             $this->media_list = array();
         }
         $filetext .= "0 @WEBTREES@ SOUR\n1 TITL " . WT_BASE_URL . "\n";
         if ($user_id = $WT_TREE->getPreference('CONTACT_EMAIL')) {
             $user = User::find($user_id);
             $filetext .= "1 AUTH " . $user->getRealName() . "\n";
         }
         $filetext .= "0 TRLR\n";
         //-- make sure the preferred line endings are used
         $filetext = preg_replace("/[\r\n]+/", WT_EOL, $filetext);
         $this->download_data = $filetext;
         $this->downloadClipping();
     }
     Session::put('cart', $this->cart);
 }
示例#16
0
 /**
  * Print an edit control for a username.
  *
  * @param string $name
  * @param string $selected
  * @param string $extra
  *
  * @return string
  */
 public static function editFieldUsername($name, $selected = '', $extra = '')
 {
     $users = array();
     foreach (User::all() as $user) {
         $users[$user->getUserName()] = $user->getRealName() . ' - ' . $user->getUserName();
     }
     // The currently selected user may not exist
     if ($selected && !array_key_exists($selected, $users)) {
         $users[$selected] = $selected;
     }
     return self::selectEditControl($name, $users, '-', $selected, $extra);
 }
示例#17
0
 /**
  * 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;
     $block = $this->getBlockSetting($block_id, 'block', '1');
     foreach (array('block') as $name) {
         if (array_key_exists($name, $cfg)) {
             ${$name} = $cfg[$name];
         }
     }
     $messages = Database::prepare("SELECT message_id, sender, subject, body, UNIX_TIMESTAMP(created) AS created FROM `##message` WHERE user_id=? ORDER BY message_id DESC")->execute(array(Auth::id()))->fetchAll();
     $count = count($messages);
     $id = $this->getName() . $block_id;
     $class = $this->getName() . '_block';
     $title = I18N::plural('%s message', '%s messages', $count, I18N::number($count));
     $users = array_filter(User::all(), function (User $user) {
         return $user->getUserId() !== Auth::id() && $user->getPreference('verified_by_admin') && $user->getPreference('contactmethod') !== 'none';
     });
     $content = '<form id="messageform" name="messageform" method="post" action="module.php?mod=user_messages&mod_action=delete" onsubmit="return confirm(\'' . I18N::translate('Are you sure you want to delete this message?  It cannot be retrieved later.') . '\');">';
     $content .= '<input type="hidden" name="ged" value="' . $ctype . '">';
     $content .= '<input type="hidden" name="ctype" value="' . $WT_TREE->getNameHtml() . '">';
     if ($users) {
         $content .= '<label for="touser">' . I18N::translate('Send a message') . '</label>';
         $content .= '<select id="touser" name="touser">';
         $content .= '<option value="">' . I18N::translate('&lt;select&gt;') . '</option>';
         foreach ($users as $user) {
             $content .= sprintf('<option value="%1$s">%2$s - %1$s</option>', Filter::escapeHtml($user->getUserName()), Filter::escapeHtml($user->getRealName()));
         }
         $content .= '</select>';
         $content .= '<input type="button" value="' . I18N::translate('Send') . '" onclick="return message(document.messageform.touser.options[document.messageform.touser.selectedIndex].value, \'messaging2\', \'\');"><br><br>';
     }
     if ($messages) {
         $content .= '<table class="list_table"><tr>';
         $content .= '<th class="list_label">' . I18N::translate('Delete') . '<br><a href="#" onclick="jQuery(\'#' . $this->getName() . $block_id . ' :checkbox\').prop(\'checked\', true); return false;">' . I18N::translate('All') . '</a></th>';
         $content .= '<th class="list_label">' . I18N::translate('Subject') . '</th>';
         $content .= '<th class="list_label">' . I18N::translate('Date sent') . '</th>';
         $content .= '<th class="list_label">' . I18N::translate('Email address') . '</th>';
         $content .= '</tr>';
         foreach ($messages as $message) {
             $content .= '<tr>';
             $content .= '<td class="list_value_wrap"><input type="checkbox" name="message_id[]" value="' . $message->message_id . '" id="cb_message' . $message->message_id . '"></td>';
             $content .= '<td class="list_value_wrap"><a href="#" onclick="return expand_layer(\'message' . $message->message_id . '\');"><i id="message' . $message->message_id . '_img" class="icon-plus"></i> <b dir="auto">' . Filter::escapeHtml($message->subject) . '</b></a></td>';
             $content .= '<td class="list_value_wrap">' . FunctionsDate::formatTimestamp($message->created + WT_TIMESTAMP_OFFSET) . '</td>';
             $content .= '<td class="list_value_wrap">';
             $user = User::findByIdentifier($message->sender);
             if ($user) {
                 $content .= $user->getRealNameHtml();
                 $content .= '  - <span dir="auto">' . $user->getEmail() . '</span>';
             } else {
                 $content .= '<a href="mailto:' . Filter::escapeHtml($message->sender) . '">' . Filter::escapeHtml($message->sender) . '</a>';
             }
             $content .= '</td>';
             $content .= '</tr>';
             $content .= '<tr><td class="list_value_wrap" colspan="4"><div id="message' . $message->message_id . '" style="display:none;">';
             $content .= '<div dir="auto" style="white-space: pre-wrap;">' . Filter::expandUrls($message->body) . '</div><br>';
             if (strpos($message->subject, I18N::translate('RE: ')) !== 0) {
                 $message->subject = I18N::translate('RE: ') . $message->subject;
             }
             if ($user) {
                 $content .= '<button type="button" onclick="reply(\'' . Filter::escapeJs($message->sender) . '\', \'' . Filter::escapeJs($message->subject) . '\'); return false;">' . I18N::translate('Reply') . '</button> ';
             }
             $content .= '<button type="button" onclick="if (confirm(\'' . I18N::translate('Are you sure you want to delete this message?  It cannot be retrieved later.') . '\')) {jQuery(\'#messageform :checkbox\').prop(\'checked\', false); jQuery(\'#cb_message' . $message->message_id . '\').prop(\'checked\', true); document.messageform.submit();}">' . I18N::translate('Delete') . '</button></div></td></tr>';
         }
         $content .= '</table>';
         $content .= '<p><button type="submit">' . I18N::translate('Delete selected messages') . '</button></p>';
     }
     $content .= '</form>';
     if ($template) {
         if ($block) {
             $class .= ' small_inner_block';
         }
         return Theme::theme()->formatBlock($id, $title, $class, $content);
     } else {
         return $content;
     }
 }
示例#18
0
        case 'themes/simplygreen/':
        case 'themes/simplyred/':
            $stmt_gedcom_setting->execute(array($GED_DATA['id'], 'THEME_DIR', 'colors'));
            break;
        case 'themes/xenea/':
            $stmt_gedcom_setting->execute(array($GED_DATA['id'], 'THEME_DIR', 'xenea'));
            break;
        default:
            $stmt_gedcom_setting->execute(array($GED_DATA['id'], 'THEME_DIR', 'webtrees'));
            break;
    }
    $stmt_gedcom_setting->execute(array($GED_DATA['id'], 'THUMBNAIL_WIDTH', $THUMBNAIL_WIDTH));
    $stmt_gedcom_setting->execute(array($GED_DATA['id'], 'USE_RELATIONSHIP_PRIVACY', $USE_RELATIONSHIP_PRIVACY));
    $stmt_gedcom_setting->execute(array($GED_DATA['id'], 'USE_RIN', $USE_RIN));
    $stmt_gedcom_setting->execute(array($GED_DATA['id'], 'WATERMARK_THUMB', $WATERMARK_THUMB));
    $stmt_gedcom_setting->execute(array($GED_DATA['id'], 'WEBMASTER_USER_ID', User::findByIdentifier($WEBMASTER_EMAIL)->getUserId()));
    $stmt_gedcom_setting->execute(array($GED_DATA['id'], 'WORD_WRAPPED_NOTES', $WORD_WRAPPED_NOTES));
}
Database::prepare("DELETE FROM `##gedcom_setting` WHERE setting_name IN ('config', 'privacy', 'path', 'pgv_ver', 'imported')")->execute();
// webtrees 1.0.5 combines user and gedcom settings for relationship privacy
// into a combined user-gedcom setting, for more granular control
Database::exec("INSERT IGNORE INTO `##user_gedcom_setting` (user_id, gedcom_id, setting_name, setting_value)" . " SELECT u.user_id, g.gedcom_id, 'RELATIONSHIP_PATH_LENGTH', LEAST(us1.setting_value, gs1.setting_value)" . " FROM   `##user` u" . " CROSS  JOIN `##gedcom` g" . " LEFT   JOIN `##user_setting`   us1 ON (u.user_id  =us1.user_id   AND us1.setting_name='max_relation_path')" . " LEFT   JOIN `##user_setting`   us2 ON (u.user_id  =us2.user_id   AND us2.setting_name='relationship_privacy')" . " LEFT   JOIN `##gedcom_setting` gs1 ON (g.gedcom_id=gs1.gedcom_id AND gs1.setting_name='MAX_RELATION_PATH_LENGTH')" . " LEFT   JOIN `##gedcom_setting` gs2 ON (g.gedcom_id=gs2.gedcom_id AND gs2.setting_name='USE_RELATIONSHIP_PRIVACY')" . " WHERE  us2.setting_value AND gs2.setting_value");
Database::exec("DELETE FROM `##gedcom_setting` WHERE setting_name IN ('MAX_RELATION_PATH_LENGTH', 'USE_RELATIONSHIP_PRIVACY')");
Database::exec("DELETE FROM `##user_setting` WHERE setting_name IN ('relationship_privacy', 'max_relation_path_length')");
////////////////////////////////////////////////////////////////////////////////
// The PhpGedView blocks don't migrate easily.
// Just give everybody and every tree default blocks
////////////////////////////////////////////////////////////////////////////////
Database::prepare("INSERT INTO `##block` (user_id, location, block_order, module_name)" . " SELECT `##user`.user_id, location, block_order, module_name" . " FROM `##block`" . " JOIN `##user`" . " WHERE `##block`.user_id = -1" . " AND   `##user`.user_id  >  0")->execute();
Database::prepare("INSERT INTO `##block` (gedcom_id, location, block_order, module_name)" . " SELECT `##gedcom`.gedcom_id, location, block_order, module_name" . " FROM `##block`" . " JOIN `##gedcom`" . " WHERE `##block`.gedcom_id = -1" . " AND   `##gedcom`.gedcom_id  >  0")->execute();
////////////////////////////////////////////////////////////////////////////////
示例#19
0
    /**
     * Print a fact record, for the individual/family/source/repository/etc. pages.
     *
     * Although a Fact has a parent object, we also need to know
     * the GedcomRecord for which we are printing it.  For example,
     * we can show the death of X on the page of Y, or the marriage
     * of X+Y on the page of Z.  We need to know both records to
     * calculate ages, relationships, etc.
     *
     * @param Fact $fact
     * @param GedcomRecord $record
     */
    public static function printFact(Fact $fact, GedcomRecord $record)
    {
        static $n_chil = 0, $n_gchi = 0;
        $parent = $fact->getParent();
        // Some facts don't get printed here ...
        switch ($fact->getTag()) {
            case 'NOTE':
                self::printMainNotes($fact, 1);
                return;
            case 'SOUR':
                self::printMainSources($fact, 1);
                return;
            case 'OBJE':
                self::printMainMedia($fact, 1);
                return;
            case 'FAMC':
            case 'FAMS':
            case 'CHIL':
            case 'HUSB':
            case 'WIFE':
                // These are internal links, not facts
                return;
            case '_WT_OBJE_SORT':
                // These links are used internally to record the sort order.
                return;
            default:
                // Hide unrecognized/custom tags?
                if ($fact->getParent()->getTree()->getPreference('HIDE_GEDCOM_ERRORS') && !GedcomTag::isTag($fact->getTag())) {
                    return;
                }
                break;
        }
        // Who is this fact about?  Need it to translate fact label correctly
        if ($parent instanceof Family && $record instanceof Individual) {
            // Family event
            $label_person = $fact->getParent()->getSpouse($record);
        } else {
            // Individual event
            $label_person = $parent;
        }
        // New or deleted facts need different styling
        $styleadd = '';
        if ($fact->isPendingAddition()) {
            $styleadd = 'new';
        }
        if ($fact->isPendingDeletion()) {
            $styleadd = 'old';
        }
        // Event of close relative
        if (preg_match('/^_[A-Z_]{3,5}_[A-Z0-9]{4}$/', $fact->getTag())) {
            $styleadd = trim($styleadd . ' rela');
        }
        // Event of close associates
        if ($fact->getFactId() == 'asso') {
            $styleadd = trim($styleadd . ' rela');
        }
        // historical facts
        if ($fact->getFactId() == 'histo') {
            $styleadd = trim($styleadd . ' histo');
        }
        // Does this fact have a type?
        if (preg_match('/\\n2 TYPE (.+)/', $fact->getGedcom(), $match)) {
            $type = $match[1];
        } else {
            $type = '';
        }
        switch ($fact->getTag()) {
            case 'EVEN':
            case 'FACT':
                if (GedcomTag::isTag($type)) {
                    // Some users (just Meliza?) use "1 EVEN/2 TYPE BIRT".  Translate the TYPE.
                    $label = GedcomTag::getLabel($type, $label_person);
                    $type = '';
                    // Do not print this again
                } elseif ($type) {
                    // We don't have a translation for $type - but a custom translation might exist.
                    $label = I18N::translate(Filter::escapeHtml($type));
                    $type = '';
                    // Do not print this again
                } else {
                    // An unspecified fact/event
                    $label = $fact->getLabel();
                }
                break;
            case 'MARR':
                // This is a hack for a proprietory extension.  Is it still used/needed?
                $utype = strtoupper($type);
                if ($utype == 'CIVIL' || $utype == 'PARTNERS' || $utype == 'RELIGIOUS') {
                    $label = GedcomTag::getLabel('MARR_' . $utype, $label_person);
                    $type = '';
                    // Do not print this again
                } else {
                    $label = $fact->getLabel();
                }
                break;
            default:
                // Normal fact/event
                $label = $fact->getLabel();
                break;
        }
        echo '<tr class="', $styleadd, '">';
        echo '<td class="descriptionbox width20">';
        if ($fact->getParent()->getTree()->getPreference('SHOW_FACT_ICONS')) {
            echo Theme::theme()->icon($fact), ' ';
        }
        if ($fact->getFactId() != 'histo' && $fact->canEdit()) {
            ?>
			<a
				href="#"
				title="<?php 
            echo I18N::translate('Edit');
            ?>
"
				onclick="return edit_record('<?php 
            echo $parent->getXref();
            ?>
', '<?php 
            echo $fact->getFactId();
            ?>
');"
				><?php 
            echo $label;
            ?>
</a>
			<div class="editfacts">
				<div class="editlink">
					<a
						href="#"
						title="<?php 
            echo I18N::translate('Edit');
            ?>
"
						class="editicon"
						onclick="return edit_record('<?php 
            echo $parent->getXref();
            ?>
', '<?php 
            echo $fact->getFactId();
            ?>
');"
						><span class="link_text"><?php 
            echo I18N::translate('Edit');
            ?>
</span></a>
				</div>
				<div class="copylink">
					<a
						href="#"
						title="<?php 
            echo I18N::translate('Copy');
            ?>
"
						class="copyicon"
						onclick="return copy_fact('<?php 
            echo $parent->getXref();
            ?>
', '<?php 
            echo $fact->getFactId();
            ?>
');"
						><span class="link_text"><?php 
            echo I18N::translate('Copy');
            ?>
</span></a>
				</div>
				<div class="deletelink">
					<a
						href="#"
						title="<?php 
            echo I18N::translate('Delete');
            ?>
"
						class="deleteicon"
						onclick="return delete_fact('<?php 
            echo I18N::translate('Are you sure you want to delete this fact?');
            ?>
', '<?php 
            echo $parent->getXref();
            ?>
', '<?php 
            echo $fact->getFactId();
            ?>
');"
						><span class="link_text"><?php 
            echo I18N::translate('Delete');
            ?>
</span></a>
				</div>
			</div>
		<?php 
        } else {
            echo $label;
        }
        switch ($fact->getTag()) {
            case '_BIRT_CHIL':
                echo '<br>', I18N::translate('#%s', ++$n_chil);
                break;
            case '_BIRT_GCHI':
            case '_BIRT_GCH1':
            case '_BIRT_GCH2':
                echo '<br>', I18N::translate('#%s', ++$n_gchi);
                break;
        }
        echo '</td><td class="optionbox ', $styleadd, ' wrap">';
        // Event from another record?
        if ($parent !== $record) {
            if ($parent instanceof Family) {
                foreach ($parent->getSpouses() as $spouse) {
                    if ($record !== $spouse) {
                        echo '<a href="', $spouse->getHtmlUrl(), '">', $spouse->getFullName(), '</a> — ';
                    }
                }
                echo '<a href="', $parent->getHtmlUrl(), '">', I18N::translate('View family'), '</a><br>';
            } elseif ($parent instanceof Individual) {
                echo '<a href="', $parent->getHtmlUrl(), '">', $parent->getFullName(), '</a><br>';
            }
        }
        // Print the value of this fact/event
        switch ($fact->getTag()) {
            case 'ADDR':
                echo $fact->getValue();
                break;
            case 'AFN':
                echo '<div class="field"><a href="https://familysearch.org/search/tree/results#count=20&query=afn:', rawurlencode($fact->getValue()), '" target="new">', Filter::escapeHtml($fact->getValue()), '</a></div>';
                break;
            case 'ASSO':
                // we handle this later, in format_asso_rela_record()
                break;
            case 'EMAIL':
            case 'EMAI':
            case '_EMAIL':
                echo '<div class="field"><a href="mailto:', Filter::escapeHtml($fact->getValue()), '">', Filter::escapeHtml($fact->getValue()), '</a></div>';
                break;
            case 'FILE':
                if (Auth::isEditor($fact->getParent()->getTree())) {
                    echo '<div class="field">', Filter::escapeHtml($fact->getValue()), '</div>';
                }
                break;
            case 'RESN':
                echo '<div class="field">';
                switch ($fact->getValue()) {
                    case 'none':
                        // Note: "1 RESN none" is not valid gedcom.
                        // However, webtrees privacy rules will interpret it as "show an otherwise private record to public".
                        echo '<i class="icon-resn-none"></i> ', I18N::translate('Show to visitors');
                        break;
                    case 'privacy':
                        echo '<i class="icon-class-none"></i> ', I18N::translate('Show to members');
                        break;
                    case 'confidential':
                        echo '<i class="icon-confidential-none"></i> ', I18N::translate('Show to managers');
                        break;
                    case 'locked':
                        echo '<i class="icon-locked-none"></i> ', I18N::translate('Only managers can edit');
                        break;
                    default:
                        echo Filter::escapeHtml($fact->getValue());
                        break;
                }
                echo '</div>';
                break;
            case 'PUBL':
                // Publication details might contain URLs.
                echo '<div class="field">', Filter::expandUrls($fact->getValue()), '</div>';
                break;
            case 'REPO':
                if (preg_match('/^@(' . WT_REGEX_XREF . ')@$/', $fact->getValue(), $match)) {
                    self::printRepositoryRecord($match[1]);
                } else {
                    echo '<div class="error">', Filter::escapeHtml($fact->getValue()), '</div>';
                }
                break;
            case 'URL':
            case '_URL':
            case 'WWW':
                echo '<div class="field"><a href="', Filter::escapeHtml($fact->getValue()), '">', Filter::escapeHtml($fact->getValue()), '</a></div>';
                break;
            case 'TEXT':
                // 0 SOUR / 1 TEXT
                echo '<div class="field">', nl2br(Filter::escapeHtml($fact->getValue()), false), '</div>';
                break;
            default:
                // Display the value for all other facts/events
                switch ($fact->getValue()) {
                    case '':
                        // Nothing to display
                        break;
                    case 'N':
                        // Not valid GEDCOM
                        echo '<div class="field">', I18N::translate('No'), '</div>';
                        break;
                    case 'Y':
                        // Do not display "Yes".
                        break;
                    default:
                        if (preg_match('/^@(' . WT_REGEX_XREF . ')@$/', $fact->getValue(), $match)) {
                            $target = GedcomRecord::getInstance($match[1], $fact->getParent()->getTree());
                            if ($target) {
                                echo '<div><a href="', $target->getHtmlUrl(), '">', $target->getFullName(), '</a></div>';
                            } else {
                                echo '<div class="error">', Filter::escapeHtml($fact->getValue()), '</div>';
                            }
                        } else {
                            echo '<div class="field"><span dir="auto">', Filter::escapeHtml($fact->getValue()), '</span></div>';
                        }
                        break;
                }
                break;
        }
        // Print the type of this fact/event
        if ($type) {
            $utype = strtoupper($type);
            // Events of close relatives, e.g. _MARR_CHIL
            if (substr($fact->getTag(), 0, 6) == '_MARR_' && ($utype == 'CIVIL' || $utype == 'PARTNERS' || $utype == 'RELIGIOUS')) {
                // Translate MARR/TYPE using the code that supports MARR_CIVIL, etc. tags
                $type = GedcomTag::getLabel('MARR_' . $utype);
            } else {
                // Allow (custom) translations for other types
                $type = I18N::translate($type);
            }
            echo GedcomTag::getLabelValue('TYPE', Filter::escapeHtml($type));
        }
        // Print the date of this fact/event
        echo FunctionsPrint::formatFactDate($fact, $record, true, true);
        // Print the place of this fact/event
        echo '<div class="place">', FunctionsPrint::formatFactPlace($fact, true, true, true), '</div>';
        // A blank line between the primary attributes (value, date, place) and the secondary ones
        echo '<br>';
        $addr = $fact->getAttribute('ADDR');
        if ($addr) {
            echo GedcomTag::getLabelValue('ADDR', $addr);
        }
        // Print the associates of this fact/event
        if ($fact->getFactId() !== 'asso') {
            echo self::formatAssociateRelationship($fact);
        }
        // Print any other "2 XXXX" attributes, in the order in which they appear.
        preg_match_all('/\\n2 (' . WT_REGEX_TAG . ') (.+)/', $fact->getGedcom(), $matches, PREG_SET_ORDER);
        foreach ($matches as $match) {
            switch ($match[1]) {
                case 'DATE':
                case 'TIME':
                case 'AGE':
                case 'PLAC':
                case 'ADDR':
                case 'ALIA':
                case 'ASSO':
                case '_ASSO':
                case 'DESC':
                case 'RELA':
                case 'STAT':
                case 'TEMP':
                case 'TYPE':
                case 'FAMS':
                case 'CONT':
                    // These were already shown at the beginning
                    break;
                case 'NOTE':
                case 'OBJE':
                case 'SOUR':
                    // These will be shown at the end
                    break;
                case 'EVEN':
                    // 0 SOUR / 1 DATA / 2 EVEN / 3 DATE / 3 PLAC
                    $events = array();
                    foreach (preg_split('/ *, */', $match[2]) as $event) {
                        $events[] = GedcomTag::getLabel($event);
                    }
                    if (count($events) == 1) {
                        echo GedcomTag::getLabelValue('EVEN', $event);
                    } else {
                        echo GedcomTag::getLabelValue('EVEN', implode(I18N::$list_separator, $events));
                    }
                    if (preg_match('/\\n3 DATE (.+)/', $fact->getGedcom(), $date_match)) {
                        $date = new Date($date_match[1]);
                        echo GedcomTag::getLabelValue('DATE', $date->display());
                    }
                    if (preg_match('/\\n3 PLAC (.+)/', $fact->getGedcom(), $plac_match)) {
                        echo GedcomTag::getLabelValue('PLAC', $plac_match[1]);
                    }
                    break;
                case 'FAMC':
                    // 0 INDI / 1 ADOP / 2 FAMC / 3 ADOP
                    $family = Family::getInstance(str_replace('@', '', $match[2]), $fact->getParent()->getTree());
                    if ($family) {
                        echo GedcomTag::getLabelValue('FAM', '<a href="' . $family->getHtmlUrl() . '">' . $family->getFullName() . '</a>');
                        if (preg_match('/\\n3 ADOP (HUSB|WIFE|BOTH)/', $fact->getGedcom(), $match)) {
                            echo GedcomTag::getLabelValue('ADOP', GedcomCodeAdop::getValue($match[1], $label_person));
                        }
                    } else {
                        echo GedcomTag::getLabelValue('FAM', '<span class="error">' . $match[2] . '</span>');
                    }
                    break;
                case '_WT_USER':
                    $user = User::findByIdentifier($match[2]);
                    // may not exist
                    if ($user) {
                        echo GedcomTag::getLabelValue('_WT_USER', $user->getRealNameHtml());
                    } else {
                        echo GedcomTag::getLabelValue('_WT_USER', Filter::escapeHtml($match[2]));
                    }
                    break;
                case 'RESN':
                    switch ($match[2]) {
                        case 'none':
                            // Note: "2 RESN none" is not valid gedcom.
                            // However, webtrees privacy rules will interpret it as "show an otherwise private fact to public".
                            echo GedcomTag::getLabelValue('RESN', '<i class="icon-resn-none"></i> ' . I18N::translate('Show to visitors'));
                            break;
                        case 'privacy':
                            echo GedcomTag::getLabelValue('RESN', '<i class="icon-resn-privacy"></i> ' . I18N::translate('Show to members'));
                            break;
                        case 'confidential':
                            echo GedcomTag::getLabelValue('RESN', '<i class="icon-resn-confidential"></i> ' . I18N::translate('Show to managers'));
                            break;
                        case 'locked':
                            echo GedcomTag::getLabelValue('RESN', '<i class="icon-resn-locked"></i> ' . I18N::translate('Only managers can edit'));
                            break;
                        default:
                            echo GedcomTag::getLabelValue('RESN', Filter::escapeHtml($match[2]));
                            break;
                    }
                    break;
                case 'CALN':
                    echo GedcomTag::getLabelValue('CALN', Filter::expandUrls($match[2]));
                    break;
                case 'FORM':
                    // 0 OBJE / 1 FILE / 2 FORM / 3 TYPE
                    echo GedcomTag::getLabelValue('FORM', $match[2]);
                    if (preg_match('/\\n3 TYPE (.+)/', $fact->getGedcom(), $type_match)) {
                        echo GedcomTag::getLabelValue('TYPE', GedcomTag::getFileFormTypeValue($type_match[1]));
                    }
                    break;
                case 'URL':
                case '_URL':
                case 'WWW':
                    $link = '<a href="' . Filter::escapeHtml($match[2]) . '">' . Filter::escapeHtml($match[2]) . '</a>';
                    echo GedcomTag::getLabelValue($fact->getTag() . ':' . $match[1], $link);
                    break;
                default:
                    if (!$fact->getParent()->getTree()->getPreference('HIDE_GEDCOM_ERRORS') || GedcomTag::isTag($match[1])) {
                        if (preg_match('/^@(' . WT_REGEX_XREF . ')@$/', $match[2], $xmatch)) {
                            // Links
                            $linked_record = GedcomRecord::getInstance($xmatch[1], $fact->getParent()->getTree());
                            if ($linked_record) {
                                $link = '<a href="' . $linked_record->getHtmlUrl() . '">' . $linked_record->getFullName() . '</a>';
                                echo GedcomTag::getLabelValue($fact->getTag() . ':' . $match[1], $link);
                            } else {
                                echo GedcomTag::getLabelValue($fact->getTag() . ':' . $match[1], Filter::escapeHtml($match[2]));
                            }
                        } else {
                            // Non links
                            echo GedcomTag::getLabelValue($fact->getTag() . ':' . $match[1], Filter::escapeHtml($match[2]));
                        }
                    }
                    break;
            }
        }
        echo self::printFactSources($fact->getGedcom(), 2);
        echo FunctionsPrint::printFactNotes($fact->getGedcom(), 2);
        self::printMediaLinks($fact->getGedcom(), 2);
        echo '</td></tr>';
    }
示例#20
0
        case 'themes/simplyblue/':
        case 'themes/simplygreen/':
        case 'themes/simplyred/':
            $stmt_gedcom_setting->execute(array($GED_DATA['id'], 'THEME_DIR', 'colors'));
            break;
        case 'themes/xenea/':
            $stmt_gedcom_setting->execute(array($GED_DATA['id'], 'THEME_DIR', 'xenea'));
            break;
        default:
            $stmt_gedcom_setting->execute(array($GED_DATA['id'], 'THEME_DIR', 'webtrees'));
            break;
    }
    $stmt_gedcom_setting->execute(array($GED_DATA['id'], 'THUMBNAIL_WIDTH', $THUMBNAIL_WIDTH));
    $stmt_gedcom_setting->execute(array($GED_DATA['id'], 'USE_RELATIONSHIP_PRIVACY', $USE_RELATIONSHIP_PRIVACY));
    $stmt_gedcom_setting->execute(array($GED_DATA['id'], 'WATERMARK_THUMB', $WATERMARK_THUMB));
    $user = User::findByIdentifier($WEBMASTER_EMAIL);
    if ($user) {
        $stmt_gedcom_setting->execute(array($GED_DATA['id'], 'WEBMASTER_USER_ID', $user->getUserId()));
    }
    $stmt_gedcom_setting->execute(array($GED_DATA['id'], 'WORD_WRAPPED_NOTES', $WORD_WRAPPED_NOTES));
}
Database::prepare("DELETE FROM `##gedcom_setting` WHERE setting_name IN ('config', 'privacy', 'path', 'pgv_ver', 'imported')")->execute();
// webtrees 1.0.5 combines user and gedcom settings for relationship privacy
// into a combined user-gedcom setting, for more granular control
Database::exec("INSERT IGNORE INTO `##user_gedcom_setting` (user_id, gedcom_id, setting_name, setting_value)" . " SELECT u.user_id, g.gedcom_id, 'RELATIONSHIP_PATH_LENGTH', LEAST(us1.setting_value, gs1.setting_value)" . " FROM   `##user` u" . " CROSS  JOIN `##gedcom` g" . " LEFT   JOIN `##user_setting`   us1 ON (u.user_id  =us1.user_id   AND us1.setting_name='max_relation_path')" . " LEFT   JOIN `##user_setting`   us2 ON (u.user_id  =us2.user_id   AND us2.setting_name='relationship_privacy')" . " LEFT   JOIN `##gedcom_setting` gs1 ON (g.gedcom_id=gs1.gedcom_id AND gs1.setting_name='MAX_RELATION_PATH_LENGTH')" . " LEFT   JOIN `##gedcom_setting` gs2 ON (g.gedcom_id=gs2.gedcom_id AND gs2.setting_name='USE_RELATIONSHIP_PRIVACY')" . " WHERE  us2.setting_value AND gs2.setting_value");
Database::exec("DELETE FROM `##gedcom_setting` WHERE setting_name IN ('MAX_RELATION_PATH_LENGTH', 'USE_RELATIONSHIP_PRIVACY')");
Database::exec("DELETE FROM `##user_setting` WHERE setting_name IN ('relationship_privacy', 'max_relation_path_length')");
////////////////////////////////////////////////////////////////////////////////
// The PhpGedView blocks don't migrate easily.
// Just give everybody and every tree default blocks
////////////////////////////////////////////////////////////////////////////////
示例#21
0
     break;
 case '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: '******'unlink-media':
     // Remove links from an individual and their spouse-family records to a media object.
     // Used by the "unlink" option on the album (lightbox) tab.
     $source = Individual::getInstance(Filter::post('source', WT_REGEX_XREF), $WT_TREE);
     $target = Filter::post('target', WT_REGEX_XREF);
     if ($source && $source->canShow() && $source->canEdit() && $target) {
         // Consider the individual and their spouse-family records
         $sources = $source->getSpouseFamilies();
示例#22
0
 /**
  * {@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;
 }
示例#23
0
$form_pass1 = Filter::post('form_pass1', WT_REGEX_PASSWORD);
$form_pass2 = Filter::post('form_pass2', WT_REGEX_PASSWORD);
$form_email = Filter::postEmail('form_email');
$form_rootid = Filter::post('form_rootid', WT_REGEX_XREF);
$form_theme = Filter::post('form_theme');
$form_language = Filter::post('form_language');
$form_timezone = Filter::post('form_timezone');
$form_contact_method = Filter::post('form_contact_method');
$form_visible_online = Filter::postBool('form_visible_online');
// Respond to form action
if ($form_action && Filter::checkCsrf()) {
    switch ($form_action) {
        case 'update':
            if ($form_username !== Auth::user()->getUserName() && User::findByUserName($form_username)) {
                FlashMessages::addMessage(I18N::translate('Duplicate user name. A user with that user name already exists. Please choose another user name.'));
            } elseif ($form_email !== Auth::user()->getEmail() && User::findByEmail($form_email)) {
                FlashMessages::addMessage(I18N::translate('Duplicate email address. A user with that email already exists.'));
            } else {
                // Change username
                if ($form_username !== Auth::user()->getUserName()) {
                    Log::addAuthenticationLog('User ' . Auth::user()->getUserName() . ' renamed to ' . $form_username);
                    Auth::user()->setUserName($form_username);
                }
                // Change password
                if ($form_pass1 && $form_pass1 === $form_pass2) {
                    Auth::user()->setPassword($form_pass1);
                }
                // Change other settings
                Auth::user()->setRealName($form_realname)->setEmail($form_email)->setPreference('language', $form_language)->setPreference('TIMEZONE', $form_timezone)->setPreference('contactmethod', $form_contact_method)->setPreference('visibleonline', $form_visible_online ? '1' : '0');
                if ($form_theme === null) {
                    Auth::user()->deletePreference('theme');
 /**
  * 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;
         }
     }
 }
示例#25
0
 /**
  * These functions provide access to hitcounter for use in the HTML block.
  *
  * @param string   $page_name
  * @param string[] $params
  *
  * @return string
  */
 private function hitCountQuery($page_name, $params)
 {
     if (is_array($params) && isset($params[0]) && $params[0] != '') {
         $page_parameter = $params[0];
     } else {
         $page_parameter = '';
     }
     if ($page_name === null) {
         // index.php?ctype=gedcom
         $page_name = 'index.php';
         $page_parameter = 'gedcom:' . ($page_parameter ? Tree::findByName($page_parameter)->getTreeId() : $this->tree->getTreeId());
     } elseif ($page_name == 'index.php') {
         // index.php?ctype=user
         $user = User::findByIdentifier($page_parameter);
         $page_parameter = 'user:'******'<span class="odometer">' . I18N::digits(HitCounter::getCount($this->tree, $page_name, $page_parameter)) . '</span>';
 }
示例#26
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;
}
示例#27
0
">
			<?php 
        } else {
            ?>
			<?php 
            echo I18N::translate('Nothing found to cleanup');
            ?>
			<?php 
        }
        ?>
		</p>
	</form>
	<?php 
        break;
    case 'cleanup2':
        foreach (User::all() as $user) {
            if (Filter::post('del_' . $user->getUserId()) == '1') {
                Log::addAuthenticationLog('Deleted user: '******'The user %s has been deleted.', Filter::escapeHtml($user->getUserName()));
            }
        }
        header('Location: ' . WT_BASE_URL . WT_SCRIPT_NAME);
        break;
    default:
        $controller->setPageTitle(I18N::translate('User administration'))->addExternalJavascript(WT_JQUERY_DATATABLES_JS_URL)->addExternalJavascript(WT_DATATABLES_BOOTSTRAP_JS_URL)->addInlineJavascript('
			jQuery(".table-user-list").dataTable({
				' . I18N::datatablesI18N() . ',
				stateSave: true,
				stateDuration: 300,
				processing: true,
示例#28
0
 /**
  * Create contact links for the page footer.
  *
  * @return string
  */
 protected function contactLinks()
 {
     $contact_user = User::find($this->tree->getPreference('CONTACT_USER_ID'));
     $webmaster_user = User::find($this->tree->getPreference('WEBMASTER_USER_ID'));
     if ($contact_user && $contact_user === $webmaster_user) {
         return $this->contactLinkEverything($contact_user);
     } elseif ($contact_user && $webmaster_user) {
         return $this->contactLinkGenealogy($contact_user) . '<br>' . $this->contactLinkTechnical($webmaster_user);
     } elseif ($contact_user) {
         return $this->contactLinkGenealogy($contact_user);
     } elseif ($webmaster_user) {
         return $this->contactLinkTechnical($webmaster_user);
     } else {
         return '';
     }
 }
示例#29
0
} else {
    // Copy these values through to the next step
    echo '<input type="hidden" name="wtname"  value="', Filter::escapeHtml($_POST['wtname']), '">';
    echo '<input type="hidden" name="wtuser"  value="', Filter::escapeHtml($_POST['wtuser']), '">';
    echo '<input type="hidden" name="wtpass"  value="', Filter::escapeHtml($_POST['wtpass']), '">';
    echo '<input type="hidden" name="wtpass2" value="', Filter::escapeHtml($_POST['wtpass2']), '">';
    echo '<input type="hidden" name="wtemail" value="', Filter::escapeHtml($_POST['wtemail']), '">';
}
////////////////////////////////////////////////////////////////////////////////
// Step six  We have a database connection and a writable folder.  Do it!
////////////////////////////////////////////////////////////////////////////////
try {
    // Create/update the database tables.
    Database::updateSchema('\\Fisharebest\\Webtrees\\Schema', 'WT_SCHEMA_VERSION', 30);
    // Create the admin user
    $admin = User::create($_POST['wtuser'], $_POST['wtname'], $_POST['wtemail'], $_POST['wtpass']);
    $admin->setPreference('canadmin', '1');
    $admin->setPreference('language', WT_LOCALE);
    $admin->setPreference('verified', '1');
    $admin->setPreference('verified_by_admin', '1');
    $admin->setPreference('auto_accept', '0');
    $admin->setPreference('visibleonline', '1');
    // Write the config file.  We already checked that this would work.
    $config_ini_php = '; <' . '?php exit; ?' . '> DO NOT DELETE THIS LINE' . PHP_EOL . 'dbhost="' . addcslashes($_POST['dbhost'], '"') . '"' . PHP_EOL . 'dbport="' . addcslashes($_POST['dbport'], '"') . '"' . PHP_EOL . 'dbuser="******"') . '"' . PHP_EOL . 'dbpass="******"') . '"' . PHP_EOL . 'dbname="' . addcslashes($_POST['dbname'], '"') . '"' . PHP_EOL . 'tblpfx="' . addcslashes($_POST['tblpfx'], '"') . '"' . PHP_EOL;
    file_put_contents(WT_DATA_DIR . 'config.ini.php', $config_ini_php);
    // Done - start using webtrees!
    echo '<script>document.location=document.location;</script>';
    echo '</form></body></html>';
} catch (PDOException $ex) {
    echo '<p class="bad">', I18N::translate('An unexpected database error occurred.'), '</p>', '<pre>', $ex->getMessage(), '</pre>', '<p class="info">', I18N::translate('The webtrees developers would be very interested to learn about this error.  If you contact them, they will help you resolve the problem.'), '</p>';
}
示例#30
0
			</div>
			<div>
				<input type="submit" value="', I18N::translate('Send'), '">
			</div>
		</form>
	</div>';
        break;
    case 'verify_hash':
        if (!Site::getPreference('USE_REGISTRATION_MODULE')) {
            header('Location: ' . WT_BASE_URL);
            return;
        }
        // switch language to webmaster settings
        $webmaster = User::find($WT_TREE->getPreference('WEBMASTER_USER_ID'));
        I18N::init($webmaster->getPreference('language'));
        $user = User::findByUserName($user_name);
        $edit_user_url = WT_BASE_URL . "admin_users.php?action=edit&amp;user_id=" . $user->getUserId();
        $mail1_body = I18N::translate('Hello administrator…') . Mail::EOL . Mail::EOL . I18N::translate('A new user (%1$s) has requested an account (%2$s) and verified an email address (%3$s).', $user->getRealNameHtml(), Filter::escapeHtml($user->getUserName()), Filter::escapeHtml($user->getEmail())) . Mail::EOL . Mail::EOL . I18N::translate('You need to review the account details.') . Mail::EOL . Mail::EOL . '<a href="' . $edit_user_url . '">' . $edit_user_url . '</a>' . Mail::EOL . Mail::EOL . I18N::translate('Set the status to “approved”.') . Mail::EOL . I18N::translate('Set the access level for each tree.') . Mail::EOL . I18N::translate('Link the user account to an individual.');
        $mail1_subject = I18N::translate('New user at %s', WT_BASE_URL . ' ' . $WT_TREE->getTitle());
        // Change to the new user’s language
        I18N::init($user->getPreference('language'));
        $controller->setPageTitle(I18N::translate('User verification'));
        $controller->pageHeader();
        echo '<div id="login-register-page">';
        echo '<h2>' . I18N::translate('User verification') . '</h2>';
        echo '<div id="user-verify">';
        if ($user && $user->checkPassword($user_password) && $user->getPreference('reg_hashcode') === $user_hashcode) {
            Mail::send($WT_TREE, $webmaster->getEmail(), $webmaster->getRealName(), $WT_TREE->getPreference('WEBTREES_EMAIL'), $WT_TREE->getPreference('WEBTREES_EMAIL'), $mail1_subject, $mail1_body);
            $mail1_method = $webmaster->getPreference('CONTACT_METHOD');
            if ($mail1_method != 'messaging3' && $mail1_method != 'mailto' && $mail1_method != 'none') {
                Database::prepare("INSERT INTO `##message` (sender, ip_address, user_id, subject, body) VALUES (? ,? ,? ,? ,?)")->execute(array($user_name, WT_CLIENT_IP, $webmaster->getUserId(), $mail1_subject, Filter::unescapeHtml($mail1_body)));