public static function send(WT_Tree $tree, $to_email, $to_name, $replyto_email, $replyto_name, $subject, $message) { try { $mail = new Zend_Mail('UTF-8'); $mail->setSubject($subject)->setBodyHtml($message)->setBodyText(WT_Filter::unescapeHtml($message))->setFrom(WT_Site::getPreference('SMTP_FROM_NAME'), $tree->preference('title'))->addTo($to_email, $to_name)->setReplyTo($replyto_email, $replyto_name)->send(WT_Mail::transport()); } catch (Exception $ex) { Log::addErrorLog('Mail: ' . $ex->getMessage()); return false; } return true; }
function format_repo_table($repos) { global $SHOW_LAST_CHANGE, $controller; $html = ''; $table_id = 'table-repo-' . Uuid::uuid4(); // lists requires a unique ID in case there are multiple lists per page $controller->addExternalJavascript(WT_JQUERY_DATATABLES_URL)->addInlineJavascript(' jQuery.fn.dataTableExt.oSort["unicode-asc" ]=function(a,b) {return a.replace(/<[^<]*>/, "").localeCompare(b.replace(/<[^<]*>/, ""))}; jQuery.fn.dataTableExt.oSort["unicode-desc"]=function(a,b) {return b.replace(/<[^<]*>/, "").localeCompare(a.replace(/<[^<]*>/, ""))}; jQuery("#' . $table_id . '").dataTable({ dom: \'<"H"pf<"dt-clear">irl>t<"F"pl>\', ' . WT_I18N::datatablesI18N() . ', jQueryUI: true, autoWidth: false, processing: true, columns: [ /* 0 name */ { type: "unicode" }, /* 1 #sour */ { dataSort: 2, class: "center" }, /* 2 #SOUR */ { type: "num", visible: false }, /* 3 CHAN */ { dataSort: 4, visible: ' . ($SHOW_LAST_CHANGE ? 'true' : 'false') . ' }, /* 4 CHAN_sort */ { visible: false }, /* 5 DELETE */ { visible: ' . (WT_USER_GEDCOM_ADMIN ? 'true' : 'false') . ', sortable: false } ], displayLength: 20, pagingType: "full_numbers" }); jQuery(".repo-list").css("visibility", "visible"); jQuery(".loading-image").css("display", "none"); '); //--table wrapper $html .= '<div class="loading-image"> </div>'; $html .= '<div class="repo-list">'; //-- table header $html .= '<table id="' . $table_id . '"><thead><tr>'; $html .= '<th>' . WT_I18N::translate('Repository name') . '</th>'; $html .= '<th>' . WT_I18N::translate('Sources') . '</th>'; $html .= '<th>#SOUR</th>'; $html .= '<th' . ($SHOW_LAST_CHANGE ? '' : '') . '>' . WT_Gedcom_Tag::getLabel('CHAN') . '</th>'; $html .= '<th' . ($SHOW_LAST_CHANGE ? '' : '') . '>CHAN</th>'; $html .= '<th> </th>'; //delete $html .= '</tr></thead>'; //-- table body $html .= '<tbody>'; foreach ($repos as $repo) { if (!$repo->canShow()) { continue; } if ($repo->isNew()) { $class = ' class="new"'; } elseif ($repo->isOld()) { $class = ' class="old"'; } else { $class = ''; } $html .= '<tr' . $class . '>'; //-- Repository name(s) $html .= '<td>'; foreach ($repo->getAllNames() as $n => $name) { if ($n) { $html .= '<br>'; } if ($n == $repo->getPrimaryName()) { $html .= '<a class="name2" href="' . $repo->getHtmlUrl() . '">' . highlight_search_hits($name['full']) . '</a>'; } else { $html .= '<a href="' . $repo->getHtmlUrl() . '">' . highlight_search_hits($name['full']) . '</a>'; } } $html .= '</td>'; //-- Linked SOURces $num = count($repo->linkedSources('REPO')); $html .= '<td>' . WT_I18N::number($num) . '</td><td>' . $num . '</td>'; //-- Last change if ($SHOW_LAST_CHANGE) { $html .= '<td>' . $repo->LastChangeTimestamp() . '</td>'; } else { $html .= '<td> </td>'; } //-- Last change hidden sort column if ($SHOW_LAST_CHANGE) { $html .= '<td>' . $repo->LastChangeTimestamp(true) . '</td>'; } else { $html .= '<td> </td>'; } //-- Delete if (WT_USER_GEDCOM_ADMIN) { $html .= '<td><div title="' . WT_I18N::translate('Delete') . '" class="deleteicon" onclick="return delete_repository(\'' . WT_I18N::translate('Are you sure you want to delete “%s”?', WT_Filter::escapeJs(WT_Filter::unescapeHtml($repo->getFullName()))) . "', '" . $repo->getXref() . '\');"><span class="link_text">' . WT_I18N::translate('Delete') . '</span></div></td>'; } else { $html .= '<td> </td>'; } $html .= '</tr>'; } $html .= '</tbody></table></div>'; return $html; }
$mail1_body .= WT_Mail::EOL . '<a href="' . WT_SERVER_NAME . WT_SCRIPT_PATH . "admin_users.php?filter=" . rawurlencode($user->getUserName()) . '">' . WT_SERVER_NAME . WT_SCRIPT_PATH . "admin_users.php?filter=" . rawurlencode($user->getUserName()) . '</a>' . WT_Mail::auditFooter(); $mail1_subject = WT_I18N::translate('New user at %s', WT_SERVER_NAME . WT_SCRIPT_PATH . ' ' . $WT_TREE->tree_title); // Change to the new user’s language WT_I18N::init($user->getSetting('language')); $controller->setPageTitle(WT_I18N::translate('User verification')); $controller->pageHeader(); echo '<div id="login-register-page">'; echo '<h2>' . WT_I18N::translate('User verification') . '</h2>'; echo '<div id="user-verify">'; echo WT_I18N::translate('The data for the user <b>%s</b> was checked.', $user_name); if ($user) { if ($user->checkPassword($user_password) && $user->getSetting('reg_hashcode') == $user_hashcode) { WT_Mail::send($WT_TREE, $webmaster->getEmail(), $webmaster->getRealName(), $WEBTREES_EMAIL, $WEBTREES_EMAIL, $mail1_subject, $mail1_body); $mail1_method = $webmaster->getSetting('CONTACT_METHOD'); if ($mail1_method != 'messaging3' && $mail1_method != 'mailto' && $mail1_method != 'none') { WT_DB::prepare("INSERT INTO `##message` (sender, ip_address, user_id, subject, body) VALUES (? ,? ,? ,? ,?)")->execute(array($user_name, $WT_REQUEST->getClientIp(), $webmaster->getUserId(), $mail1_subject, WT_Filter::unescapeHtml($mail1_body))); } $user->setSetting('verified', 1)->setSetting('reg_timestamp', date("U"))->setSetting('reg_hashcode', null); if (!$REQUIRE_ADMIN_AUTH_REGISTRATION) { set_user_setting($user_id, 'verified_by_admin', 1); } Log::addAuthenticationLog('User ' . $user_name . ' verified their email address'); echo '<br><br>' . WT_I18N::translate('You have confirmed your request to become a registered user.') . '<br><br>'; if ($REQUIRE_ADMIN_AUTH_REGISTRATION && !$user->getSetting('verified_by_admin')) { echo WT_I18N::translate('The administrator has been informed. As soon as he gives you permission to login, you can login with your user name and password.'); } else { echo WT_I18N::translate('You can now login with your user name and password.'); } echo '<br><br>'; } else { Log::addAuthenticationLog('User ' . $user_name . ' failed to verify their email address');
/** * Generate both the HTML and PNG components of the fan chart * * The HTML and PNG components both require the same co-ordinate calculations, * so we generate them using the same code, but we send them in separate * HTTP requests. * * @param string $what "png" or "html" * @param string[] $fanChart Presentation parameters, provided by the theme. * * @return string */ public function generate_fan_chart($what, $fanChart) { $treeid = ancestry_array($this->root->getXref(), $this->generations); $fanw = 640 * $this->fan_width / 100; $fandeg = 90 * $this->fan_style; $html = ''; $treesize = count($treeid); // generations count $gen = log($treesize) / log(2) - 1; $sosa = $treesize - 1; // fan size if ($fandeg == 0) { $fandeg = 360; } $fandeg = min($fandeg, 360); $fandeg = max($fandeg, 90); $cx = $fanw / 2 - 1; // center x $cy = $cx; // center y $rx = $fanw - 1; $rw = $fanw / ($gen + 1); $fanh = $fanw; // fan height if ($fandeg == 180) { $fanh = round($fanh * ($gen + 1) / ($gen * 2)); } if ($fandeg == 270) { $fanh = round($fanh * 0.86); } $scale = $fanw / 640; // image init $image = ImageCreate($fanw, $fanh); $white = ImageColorAllocate($image, 0xff, 0xff, 0xff); ImageFilledRectangle($image, 0, 0, $fanw, $fanh, $white); ImageColorTransparent($image, $white); $color = ImageColorAllocate($image, hexdec(substr($fanChart['color'], 1, 2)), hexdec(substr($fanChart['color'], 3, 2)), hexdec(substr($fanChart['color'], 5, 2))); $bgcolor = ImageColorAllocate($image, hexdec(substr($fanChart['bgColor'], 1, 2)), hexdec(substr($fanChart['bgColor'], 3, 2)), hexdec(substr($fanChart['bgColor'], 5, 2))); $bgcolorM = ImageColorAllocate($image, hexdec(substr($fanChart['bgMColor'], 1, 2)), hexdec(substr($fanChart['bgMColor'], 3, 2)), hexdec(substr($fanChart['bgMColor'], 5, 2))); $bgcolorF = ImageColorAllocate($image, hexdec(substr($fanChart['bgFColor'], 1, 2)), hexdec(substr($fanChart['bgFColor'], 3, 2)), hexdec(substr($fanChart['bgFColor'], 5, 2))); // imagemap $imagemap = '<map id="fanmap" name="fanmap">'; // loop to create fan cells while ($gen >= 0) { // clean current generation area $deg2 = 360 + ($fandeg - 180) / 2; $deg1 = $deg2 - $fandeg; ImageFilledArc($image, $cx, $cy, $rx, $rx, $deg1, $deg2, $bgcolor, IMG_ARC_PIE); $rx -= 3; // calculate new angle $p2 = pow(2, $gen); $angle = $fandeg / $p2; $deg2 = 360 + ($fandeg - 180) / 2; $deg1 = $deg2 - $angle; // special case for rootid cell if ($gen == 0) { $deg1 = 90; $deg2 = 360 + $deg1; } // draw each cell while ($sosa >= $p2) { $pid = $treeid[$sosa]; $person = WT_Individual::getInstance($pid); if ($person) { $name = WT_Filter::unescapeHtml($person->getFullName()); $addname = WT_Filter::unescapeHtml($person->getAddName()); $text = WT_I18N::reverseText($name); if ($addname) { $text .= "\n" . WT_I18N::reverseText($addname); } $text .= "\n" . WT_I18N::reverseText($person->getLifeSpan()); switch ($person->getSex()) { case 'M': $bg = $bgcolorM; break; case 'F': $bg = $bgcolorF; break; case 'U': $bg = $bgcolor; break; } ImageFilledArc($image, $cx, $cy, $rx, $rx, $deg1, $deg2, $bg, IMG_ARC_PIE); // split and center text by lines $wmax = (int) ($angle * 7 / $fanChart['size'] * $scale); $wmax = min($wmax, 35 * $scale); if ($gen == 0) { $wmax = min($wmax, 17 * $scale); } $text = $this->split_align_text($text, $wmax); // text angle $tangle = 270 - ($deg1 + $angle / 2); if ($gen == 0) { $tangle = 0; } // calculate text position $deg = $deg1 + 0.44; if ($deg2 - $deg1 > 40) { $deg = $deg1 + ($deg2 - $deg1) / 11; } if ($deg2 - $deg1 > 80) { $deg = $deg1 + ($deg2 - $deg1) / 7; } if ($deg2 - $deg1 > 140) { $deg = $deg1 + ($deg2 - $deg1) / 4; } if ($gen == 0) { $deg = 180; } $rad = deg2rad($deg); $mr = ($rx - $rw / 4) / 2; if ($gen > 0 && $deg2 - $deg1 > 80) { $mr = $rx / 2; } $tx = $cx + $mr * cos($rad); $ty = $cy - $mr * -sin($rad); if ($sosa == 1) { $ty -= $mr / 2; } // print text ImageTtfText($image, (double) $fanChart['size'], $tangle, $tx, $ty, $color, $fanChart['font'], $text); $imagemap .= '<area shape="poly" coords="'; // plot upper points $mr = $rx / 2; $deg = $deg1; while ($deg <= $deg2) { $rad = deg2rad($deg); $tx = round($cx + $mr * cos($rad)); $ty = round($cy - $mr * -sin($rad)); $imagemap .= "{$tx},{$ty},"; $deg += ($deg2 - $deg1) / 6; } // plot lower points $mr = ($rx - $rw) / 2; $deg = $deg2; while ($deg >= $deg1) { $rad = deg2rad($deg); $tx = round($cx + $mr * cos($rad)); $ty = round($cy - $mr * -sin($rad)); $imagemap .= "{$tx},{$ty},"; $deg -= ($deg2 - $deg1) / 6; } // join first point $mr = $rx / 2; $deg = $deg1; $rad = deg2rad($deg); $tx = round($cx + $mr * cos($rad)); $ty = round($cy - $mr * -sin($rad)); $imagemap .= "{$tx},{$ty}"; // add action url $imagemap .= '" href="' . $person->getHtmlUrl() . '"'; $tempURL = 'fanchart.php?rootid=' . $pid . '&generations=' . $this->generations . '&fan_width=' . $this->fan_width . '&fan_style=' . $this->fan_style . '&ged=' . WT_GEDURL; $count = 0; $html .= '<div id="I' . $pid . '.' . $count . 'links" style="position:absolute;'; $html .= 'left:' . $tx . 'px; top:' . $ty . 'px; width:200px; visibility:hidden; z-index:100;">'; $html .= '<table class="person_box"><tr><td class="details1">'; $html .= '<a href="' . $person->getHtmlUrl() . '" class="name1">' . $name; if ($addname) { $html .= '<br>' . $addname; } $html .= '</a>'; $html .= '<br><a href="pedigree.php?rootid=' . $pid . '&amp;ged=' . WT_GEDURL . '" >' . WT_I18N::translate('Pedigree') . '</a>'; if (array_key_exists('googlemap', WT_Module::getActiveModules())) { $html .= '<br><a href="module.php?mod=googlemap&mod_action=pedigree_map&rootid=' . $pid . '&ged=' . WT_GEDURL . '" onmouseover="clear_family_box_timeout(\'' . $pid . '.' . $count . '\');" onmouseout="family_box_timeout(\'' . $pid . "." . $count . '\');">' . WT_I18N::translate('Pedigree map') . '</a>'; } if (WT_USER_GEDCOM_ID && WT_USER_GEDCOM_ID != $pid) { $html .= '<br><a href="relationship.php?pid1=' . WT_USER_GEDCOM_ID . '&pid2=' . $pid . '&ged=' . WT_GEDURL . '" onmouseover="clear_family_box_timeout(\'' . $pid . '.' . $count . '\');" onmouseout="family_box_timeout(\'' . $pid . '.' . $count . '\');">' . WT_I18N::translate('Relationship to me') . '</a>'; } $html .= '<br><a href="descendancy.php?rootid=' . $pid . '&ged=' . WT_GEDURL . '" >' . WT_I18N::translate('Descendants') . '</a>'; $html .= '<br><a href="ancestry.php?rootid=' . $pid . '&ged=' . WT_GEDURL . '" onmouseover="clear_family_box_timeout(\'' . $pid . '.' . $count . '\');" onmouseout="family_box_timeout(\'' . $pid . '.' . $count . '\');">' . WT_I18N::translate('Ancestors') . '</a>'; $html .= '<br><a href="compact.php?rootid=' . $pid . '&ged=' . WT_GEDURL . '" onmouseover="clear_family_box_timeout(\'' . $pid . '.' . $count . '\');" onmouseout="family_box_timeout(\'' . $pid . '.' . $count . '\');">' . WT_I18N::translate('Compact tree') . '</a>'; $html .= '<br><a href="' . $tempURL . '" onmouseover="clear_family_box_timeout(\'' . $pid . '.' . $count . '\');" onmouseout="family_box_timeout(\'' . $pid . '.' . $count . '\');">' . WT_I18N::translate('Fan chart') . '</a>'; $html .= '<br><a href="hourglass.php?rootid=' . $pid . '&ged=' . WT_GEDURL . '" onmouseover="clear_family_box_timeout(\'' . $pid . '.' . $count . '\');" onmouseout="family_box_timeout(\'' . $pid . "." . $count . '\');">' . WT_I18N::translate('Hourglass chart') . '</a>'; if (array_key_exists('tree', WT_Module::getActiveModules())) { $html .= "<br><a href=\"module.php?mod=tree&mod_action=treeview&ged=" . WT_GEDURL . '&rootid=' . $pid . '" onmouseover="clear_family_box_timeout(\'' . $pid . '.' . $count . '\');" onmouseout="family_box_timeout(\'' . $pid . '.' . $count . '\');">' . WT_I18N::translate('Interactive tree') . '</a>'; } // spouse(s) and children foreach ($person->getSpouseFamilies() as $family) { $spouse = $family->getSpouse($person); if ($spouse) { $html .= '<br><a href="' . $spouse->getHtmlUrl() . '" class="name1">' . $spouse->getFullName() . '</a>'; foreach ($family->getChildren() as $child) { $html .= '<br> <a href="' . $child->getHtmlUrl() . '" class="name1">< ' . $child->getFullName() . '</a>'; } } } // siblings foreach ($person->getChildFamilies() as $family) { $children = $family->getChildren(); if (count($children) > 2) { $html .= '<br><span class="name1">' . WT_I18N::translate('Siblings') . '</span>'; } elseif (count($children) == 2) { $html .= '<br><span class="name1">' . WT_I18N::translate('Sibling') . '</span>'; } foreach ($children as $sibling) { if ($sibling !== $person) { $html .= '<br> <a href="' . $sibling->getHtmlUrl() . '" class="name1"> ' . $sibling->getFullName() . '</a>'; } } } $html .= '</td></tr></table>'; $html .= '</div>'; $imagemap .= ' onclick="show_family_box(\'' . $pid . '.' . $count . '\', \'relatives\'); return false;"'; $imagemap .= ' onmouseout="family_box_timeout(\'' . $pid . '.' . $count . '\'); return false;"'; $imagemap .= ' alt="' . WT_Filter::escapeHtml(strip_tags($name)) . '" title="' . WT_Filter::escapeHtml(strip_tags($name)) . '">'; } $deg1 -= $angle; $deg2 -= $angle; $sosa--; } $rx -= $rw; $gen--; } $imagemap .= '</map>'; switch ($what) { case 'html': $image_title = WT_I18N::translate('Fan chart of %s', strip_tags($name)); return $html . $imagemap . '<p align="center"><img src="' . WT_SCRIPT_NAME . '?rootid=' . $this->rootid . '&fan_style=' . $this->fan_style . '&generations=' . $this->generations . '&fan_width=' . $this->fan_width . '&img=1" width="' . $fanw . '" height="' . $fanh . '" alt="' . $image_title . '" title="' . $image_title . '" usemap="#fanmap"></p>'; case 'png': header('Content-Type: image/png'); ImageStringUp($image, 1, $fanw - 10, $fanh / 3, WT_SERVER_NAME . WT_SCRIPT_PATH, $color); ImagePng($image); ImageDestroy($image); } }
/** * UTF8 version of PHP::strrev() * * Reverse RTL text for third-party libraries such as GD2 and googlechart. * * These do not support UTF8 text direction, so we must mimic it for them. * * Numbers are always rendered LTR, even in RTL text. * The visual direction of characters such as parentheses should be reversed. * * @param string $text Text to be reversed * * @return string */ public static function reverseText($text) { // Remove HTML markup - we can't display it and it is LTR. $text = WT_Filter::unescapeHtml($text); // LTR text doesn't need reversing if (self::scriptDirection(self::textScript($text)) == 'ltr') { return $text; } // Mirrored characters $text = strtr($text, self::$mirror_characters); $reversed = ''; $digits = ''; while ($text != '') { $letter = mb_substr($text, 0, 1); $text = mb_substr($text, 1); if (strpos(self::DIGITS, $letter) !== false) { $digits .= $letter; } else { $reversed = $letter . $digits . $reversed; $digits = ''; } } return $digits . $reversed; }