/** * Create resources for the colors theme. */ public function hookAfterInit() { $this->palettes = array('aquamarine' => I18N::translate('Aqua Marine'), 'ash' => I18N::translate('Ash'), 'belgianchocolate' => I18N::translate('Belgian Chocolate'), 'bluelagoon' => I18N::translate('Blue Lagoon'), 'bluemarine' => I18N::translate('Blue Marine'), 'coffeeandcream' => I18N::translate('Coffee and Cream'), 'coldday' => I18N::translate('Cold Day'), 'greenbeam' => I18N::translate('Green Beam'), 'mediterranio' => I18N::translate('Mediterranio'), 'mercury' => I18N::translate('Mercury'), 'nocturnal' => I18N::translate('Nocturnal'), 'olivia' => I18N::translate('Olivia'), 'pinkplastic' => I18N::translate('Pink Plastic'), 'sage' => I18N::translate('Sage'), 'shinytomato' => I18N::translate('Shiny Tomato'), 'tealtop' => I18N::translate('Teal Top')); uasort($this->palettes, '\\Fisharebest\\Webtrees\\I18N::strcasecmp'); // If we've selected a new palette, and we are logged in, set this value as a default. if (isset($_GET['themecolor']) && array_key_exists($_GET['themecolor'], $this->palettes)) { // Request to change color $this->palette = $_GET['themecolor']; Auth::user()->setPreference('themecolor', $this->palette); if (Auth::isAdmin()) { Site::setPreference('DEFAULT_COLOR_PALETTE', $this->palette); } unset($_GET['themecolor']); // Rember that we have selected a value Session::put('subColor', $this->palette); } // If we are logged in, use our preference $this->palette = Auth::user()->getPreference('themecolor'); // If not logged in or no preference, use one we selected earlier in the session? if (!$this->palette) { $this->palette = Session::get('subColor'); } // We haven't selected one this session? Use the site default if (!$this->palette) { $this->palette = Site::getPreference('DEFAULT_COLOR_PALETTE'); } // Make sure our selected palette actually exists if (!array_key_exists($this->palette, $this->palettes)) { $this->palette = 'ash'; } }
/** * Default buttons are update and update_all * * @param string $xref * * @return string[] */ public function getActionButtons($xref) { if (Auth::user()->getPreference('auto_accept')) { return array(BatchUpdateModule::createSubmitButton(I18N::translate('Update'), $xref, 'update'), BatchUpdateModule::createSubmitButton(I18N::translate('Update all'), $xref, 'update_all')); } else { return array(BatchUpdateModule::createSubmitButton(I18N::translate('Update'), $xref, 'update')); } }
/** * Return a menu item for this chart. * * @param Individual $individual * * @return Menu|null */ public function getChartMenu(Individual $individual) { $tree = $individual->getTree(); $gedcomid = $tree->getUserPreference(Auth::user(), 'gedcomid'); if ($gedcomid) { return new Menu(I18N::translate('Relationship to me'), 'relationship.php?pid1=' . $gedcomid . '&pid2=' . $individual->getXref() . '&ged=' . $tree->getNameUrl(), 'menu-chart-relationship', array('rel' => 'nofollow')); } else { return new Menu(I18N::translate('Relationships'), 'relationship.php?pid1=' . $individual->getXref() . '&ged=' . $tree->getNameUrl(), 'menu-chart-relationship', array('rel' => 'nofollow')); } }
/** * {@inheritDoc} * @see \MyArtJaub\Webtrees\Mvc\Controller\MvcController::__construct(AbstractModule $module) */ public function __construct(AbstractModule $module) { global $WT_TREE; parent::__construct($module); $this->sosa_provider = new SosaProvider($WT_TREE, Auth::user()); $this->generation = Filter::getInteger('gen'); $this->view_bag = new ViewBag(); $this->view_bag->set('generation', $this->generation); $this->view_bag->set('max_gen', $this->sosa_provider->getLastGeneration()); $this->view_bag->set('is_setup', $this->sosa_provider->isSetup() && $this->view_bag->get('max_gen', 0) > 0); }
/** * Create a branches list controller */ public function __construct() { global $WT_TREE; parent::__construct(); $this->surname = Filter::get('surname'); $this->soundex_std = Filter::getBool('soundex_std'); $this->soundex_dm = Filter::getBool('soundex_dm'); if ($this->surname) { $this->setPageTitle(I18N::translate('Branches of the %s family', Filter::escapeHtml($this->surname))); $this->loadIndividuals(); $self = Individual::getInstance($WT_TREE->getUserPreference(Auth::user(), 'gedcomid'), $WT_TREE); if ($self) { $this->loadAncestors($self, 1); } } else { $this->setPageTitle(I18N::translate('Branches')); } }
/** * 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 = '<span dir="auto">' . I18N::translate('Welcome %s', Auth::user()->getRealNameHtml()) . '</span>'; $content = '<table><tr>'; $content .= '<td><a href="edituser.php"><i class="icon-mypage"></i><br>' . I18N::translate('My account') . '</a></td>'; $gedcomid = $WT_TREE->getUserPreference(Auth::user(), 'gedcomid'); if ($gedcomid) { $content .= '<td><a href="pedigree.php?rootid=' . $gedcomid . '&ged=' . $WT_TREE->getNameUrl() . '"><i class="icon-pedigree"></i><br>' . I18N::translate('My pedigree') . '</a></td>'; $content .= '<td><a href="individual.php?pid=' . $gedcomid . '&ged=' . $WT_TREE->getNameUrl() . '"><i class="icon-indis"></i><br>' . I18N::translate('My individual record') . '</a></td>'; } $content .= '</tr></table>'; if ($template) { return Theme::theme()->formatBlock($id, $title, $class, $content); } else { return $content; } }
/** * Main entry point * * @return string */ private function main() { global $WT_TREE; $this->plugins = $this->getPluginList(); // List of available plugins $this->plugin = Filter::get('plugin'); // User parameters $this->xref = Filter::get('xref', WT_REGEX_XREF); $this->action = Filter::get('action'); $this->data = Filter::get('data'); // Don't do any processing until a plugin is chosen. if ($this->plugin && array_key_exists($this->plugin, $this->plugins)) { $this->PLUGIN = new $this->plugin(); $this->PLUGIN->getOptions(); $this->getAllXrefs(); switch ($this->action) { case 'update': $record = self::getLatestRecord($this->xref, $this->all_xrefs[$this->xref]); if ($this->PLUGIN->doesRecordNeedUpdate($this->xref, $record)) { $newrecord = $this->PLUGIN->updateRecord($this->xref, $record); if ($newrecord != $record) { if ($newrecord) { GedcomRecord::getInstance($this->xref, $WT_TREE)->updateRecord($newrecord, $this->PLUGIN->chan); } else { GedcomRecord::getInstance($this->xref, $WT_TREE)->deleteRecord(); } } } $this->xref = $this->findNextXref($this->xref); break; case 'update_all': foreach ($this->all_xrefs as $xref => $type) { $record = self::getLatestRecord($xref, $type); if ($this->PLUGIN->doesRecordNeedUpdate($xref, $record)) { $newrecord = $this->PLUGIN->updateRecord($xref, $record); if ($newrecord != $record) { if ($newrecord) { GedcomRecord::getInstance($xref, $WT_TREE)->updateRecord($newrecord, $this->PLUGIN->chan); } else { GedcomRecord::getInstance($xref, $WT_TREE)->deleteRecord(); } } } } $this->xref = ''; break; } // Make sure that our requested record really does need updating. // It may have been updated in another session, or may not have // been specified at all. if (array_key_exists($this->xref, $this->all_xrefs) && $this->PLUGIN->doesRecordNeedUpdate($this->xref, self::getLatestRecord($this->xref, $this->all_xrefs[$this->xref]))) { $this->curr_xref = $this->xref; } // The requested record doesn't need updating - find one that does if (!$this->curr_xref) { $this->curr_xref = $this->findNextXref($this->xref); } if (!$this->curr_xref) { $this->curr_xref = $this->findPrevXref($this->xref); } // If we've found a record to update, get details and look for the next/prev if ($this->curr_xref) { $this->prev_xref = $this->findPrevXref($this->curr_xref); $this->next_xref = $this->findNextXref($this->curr_xref); } } // HTML common to all pages $controller = new PageController(); $controller->setPageTitle(I18N::translate('Batch update'))->restrictAccess(Auth::isAdmin())->pageHeader(); echo $this->getJavascript(); ?> <ol class="breadcrumb small"> <li><a href="admin.php"><?php echo I18N::translate('Control panel'); ?> </a></li> <li><a href="admin_modules.php"><?php echo I18N::translate('Module administration'); ?> </a></li> <li class="active"><?php echo $controller->getPageTitle(); ?> </li> </ol> <h2><?php echo $controller->getPageTitle(); ?> </h2> <form id="batch_update_form" class="form-horizontal" action="module.php" method="get"> <input type="hidden" name="mod" value="batch_update"> <input type="hidden" name="mod_action" value="admin_batch_update"> <input type="hidden" name="xref" value="' . $this->xref . '"> <input type="hidden" name="action" value=""><?php // will be set by javascript for next update ?> <input type="hidden" name="data" value=""><?php // will be set by javascript for next update ?> <div class="form-group"> <label class="control-label col-sm-3"><?php echo I18N::translate('Family tree'); ?> </label> <div class="col-sm-9"> <?php echo FunctionsEdit::selectEditControl('ged', Tree::getNameList(), '', $WT_TREE->getName(), 'class="form-control" onchange="reset_reload();"'); ?> </div> </div> <div class="form-group"> <label class="control-label col-sm-3"><?php echo I18N::translate('Batch update'); ?> </label> <div class="col-sm-9"> <select class="form-control" name="plugin" onchange="reset_reload();"> <?php if (!$this->plugin) { ?> <option value="" selected></option> <?php } ?> <?php foreach ($this->plugins as $class => $plugin) { ?> <option value="<?php echo $class; ?> " <?php echo $this->plugin == $class ? 'selected' : ''; ?> ><?php echo $plugin->getName(); ?> </option> <?php } ?> </select> <?php if ($this->PLUGIN) { ?> <p class="small text-muted"><?php echo $this->PLUGIN->getDescription(); ?> </p> <?php } ?> </div> </div> <?php if (!Auth::user()->getPreference('auto_accept')) { ?> <div class="alert alert-danger"> <?php echo I18N::translate('Your user account does not have “automatically approve changes” enabled. You will only be able to change one record at a time.'); ?> </div> <?php } ?> <?php // If a plugin is selected, display the details ?> <?php if ($this->PLUGIN) { ?> <?php echo $this->PLUGIN->getOptionsForm(); ?> <?php if (substr($this->action, -4) == '_all') { ?> <?php // Reset - otherwise we might "undo all changes", which refreshes the ?> <?php // page, which makes them all again! ?> <script>reset_reload();</script> <?php } else { ?> <hr> <div id="batch_update2" class="col-sm-12"> <?php if ($this->curr_xref) { ?> <?php // Create an object, so we can get the latest version of the name. ?> <?php $this->record = GedcomRecord::getInstance($this->curr_xref, $WT_TREE); ?> <div class="form-group"> <?php echo self::createSubmitButton(I18N::translate('previous'), $this->prev_xref); ?> <?php echo self::createSubmitButton(I18N::translate('next'), $this->next_xref); ?> </div> <div class="form-group"> <a class="lead" href="<?php echo $this->record->getHtmlUrl(); ?> "><?php echo $this->record->getFullName(); ?> </a> <?php echo $this->PLUGIN->getActionPreview($this->record); ?> </div> <div class="form-group"> <?php echo implode(' ', $this->PLUGIN->getActionButtons($this->curr_xref, $this->record)); ?> </div> <?php } else { ?> <div class="alert alert-info"><?php echo I18N::translate('Nothing found.'); ?> </div> <?php } ?> </div> <?php } ?> <?php } ?> </form> <?php }
/** * Constructor for SosaStatsController * @param AbstractModule $module */ public function __construct(AbstractModule $module) { global $WT_TREE; parent::__construct($module); $this->sosa_provider = new SosaProvider($WT_TREE, Auth::user()); }
/** * For relationship privacy calculations - is this individual a close relative? * * @param Individual $target * @param int $distance * * @return bool */ private static function isRelated(Individual $target, $distance) { static $cache = null; $user_individual = self::getInstance($target->tree->getUserPreference(Auth::user(), 'gedcomid'), $target->tree); if ($user_individual) { if (!$cache) { $cache = array(0 => array($user_individual), 1 => array()); foreach ($user_individual->getFacts('FAM[CS]', false, Auth::PRIV_HIDE) as $fact) { $family = $fact->getTarget(); if ($family) { $cache[1][] = $family; } } } } else { // No individual linked to this account? Cannot use relationship privacy. return true; } // Double the distance, as we count the INDI-FAM and FAM-INDI links separately $distance *= 2; // Consider each path length in turn for ($n = 0; $n <= $distance; ++$n) { if (array_key_exists($n, $cache)) { // We have already calculated all records with this length if ($n % 2 == 0 && in_array($target, $cache[$n], true)) { return true; } } else { // Need to calculate these paths $cache[$n] = array(); if ($n % 2 == 0) { // Add FAM->INDI links foreach ($cache[$n - 1] as $family) { foreach ($family->getFacts('HUSB|WIFE|CHIL', false, Auth::PRIV_HIDE) as $fact) { $individual = $fact->getTarget(); // Don’t backtrack if ($individual && !in_array($individual, $cache[$n - 2], true)) { $cache[$n][] = $individual; } } } if (in_array($target, $cache[$n], true)) { return true; } } else { // Add INDI->FAM links foreach ($cache[$n - 1] as $individual) { foreach ($individual->getFacts('FAM[CS]', false, Auth::PRIV_HIDE) as $fact) { $family = $fact->getTarget(); // Don’t backtrack if ($family && !in_array($family, $cache[$n - 2], true)) { $cache[$n][] = $family; } } } } } } return false; }
// Long lists can be broken down by given name $show_all_firstnames = Filter::get('show_all_firstnames', 'no|yes', 'no'); if ($show_all_firstnames === 'yes') { $falpha = ''; } else { $falpha = Filter::get('falpha'); // All first names beginning with this letter } $show_marnm = Filter::get('show_marnm', 'no|yes'); switch ($show_marnm) { case 'no': case 'yes': Auth::user()->setPreference(WT_SCRIPT_NAME . '_show_marnm', $show_marnm); break; default: $show_marnm = Auth::user()->getPreference(WT_SCRIPT_NAME . '_show_marnm'); } // Make sure selections are consistent. // i.e. can’t specify show_all and surname at the same time. if ($show_all === 'yes') { if ($show_all_firstnames === 'yes') { $alpha = ''; $surname = ''; $legend = I18N::translate('All'); $url = WT_SCRIPT_NAME . '?show_all=yes&ged=' . $WT_TREE->getNameUrl(); $show = 'indi'; } elseif ($falpha) { $alpha = ''; $surname = ''; $legend = I18N::translate('All') . ', ' . Filter::escapeHtml($falpha) . '…'; $url = WT_SCRIPT_NAME . '?show_all=yes&ged=' . $WT_TREE->getNameUrl();
define('WT_LOGIN_URL', WT_BASE_URL . 'login.php'); } // If there is no current tree and we need one, then redirect somewhere if (WT_SCRIPT_NAME != 'admin_trees_manage.php' && WT_SCRIPT_NAME != 'admin_pgv_to_wt.php' && WT_SCRIPT_NAME != 'login.php' && WT_SCRIPT_NAME != 'logout.php' && WT_SCRIPT_NAME != 'import.php' && WT_SCRIPT_NAME != 'help_text.php' && WT_SCRIPT_NAME != 'message.php' && WT_SCRIPT_NAME != 'action.php') { if (!$WT_TREE || !$WT_TREE->getPreference('imported')) { if (Auth::isAdmin()) { header('Location: ' . WT_BASE_URL . 'admin_trees_manage.php'); } else { header('Location: ' . WT_LOGIN_URL . '?url=' . rawurlencode(WT_SCRIPT_NAME . (isset($_SERVER['QUERY_STRING']) ? '?' . $_SERVER['QUERY_STRING'] : '')), true, 301); } exit; } } // Update the last-login time no more than once a minute if (WT_TIMESTAMP - Session::get('activity_time') >= 60) { Auth::user()->setPreference('sessiontime', WT_TIMESTAMP); Session::put('activity_time', WT_TIMESTAMP); } // Set the theme if (substr(WT_SCRIPT_NAME, 0, 5) === 'admin' || WT_SCRIPT_NAME === 'module.php' && substr(Filter::get('mod_action'), 0, 5) === 'admin') { // Administration scripts begin with “admin” and use a special administration theme Theme::theme(new AdministrationTheme())->init($WT_TREE); } else { // Last theme used? $theme_id = Session::get('theme_id'); // Default for tree if (!array_key_exists($theme_id, Theme::themeNames()) && $WT_TREE) { $theme_id = $WT_TREE->getPreference('THEME_DIR'); } // Default for site if (!array_key_exists($theme_id, Theme::themeNames())) {
if ($filter) { echo $filter; } echo '" autofocus> <p><input type="submit" name="search" value="', I18N::translate('Filter'), '" onclick="this.form.subclick.value=this.name"> <input type="submit" name="all" value="', I18N::translate('Display all'), '" onclick="this.form.subclick.value=this.name"> </p></form></div>'; } // Show specialchar and hide the rest if ($type == 'specialchar') { $language_filter = Filter::get('language_filter', null, Auth::user()->getPreference('default_language_filter')); $specialchar_languages = SpecialChars::allLanguages(); if (!array_key_exists($language_filter, $specialchar_languages)) { $language_filter = 'en'; } Auth::user()->setPreference('default_language_filter', $language_filter); $action = 'filter'; echo '<div id="find-header"> <form name="filterspecialchar" method="get" action="find.php"> <input type="hidden" name="action" value="filter"> <input type="hidden" name="type" value="specialchar"> <input type="hidden" name="callback" value="' . $callback . '"> <p><select id="language_filter" name="language_filter" onchange="submit();">'; foreach (SpecialChars::allLanguages() as $lanuguage_tag => $language_name) { echo '<option value="' . $lanuguage_tag . '" '; if ($lanuguage_tag === $language_filter) { echo 'selected'; } echo '>', $language_name, '</option>'; } echo '</select>
/** * Get the current user's full name. * * @return string */ public function userFullName() { return Auth::check() ? Auth::user()->getRealNameHtml() : ''; }
* GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ namespace Fisharebest\Webtrees; use Fisharebest\Webtrees\Controller\AjaxController; use Fisharebest\Webtrees\Functions\FunctionsImport; use PDOException; define('WT_SCRIPT_NAME', 'import.php'); require './includes/session.php'; // Don't use ged=XX as we want to be able to run without changing the current gedcom. // This will let us load several gedcoms together, or to edit one while loading another. $gedcom_id = Filter::getInteger('gedcom_id'); $tree = Tree::findById($gedcom_id); if (!$tree || !Auth::isManager($tree, Auth::user())) { http_response_code(403); return; } $controller = new AjaxController(); $controller->pageHeader(); // Don't allow the user to cancel the request. We do not want to be left // with an incomplete transaction. ignore_user_abort(true); // Run in a transaction Database::beginTransaction(); // Only allow one process to import each gedcom at a time Database::prepare("SELECT * FROM `##gedcom_chunk` WHERE gedcom_id=? FOR UPDATE")->execute(array($gedcom_id)); // What is the current import status? $row = Database::prepare("SELECT" . " SUM(IF(imported, LENGTH(chunk_data), 0)) AS import_offset," . " SUM(LENGTH(chunk_data)) AS import_total" . " FROM `##gedcom_chunk` WHERE gedcom_id=?")->execute(array($gedcom_id))->fetchOneRow(); if ($row->import_offset == $row->import_total) {
} } } } } else { http_response_code(406); } break; case 'reject-changes': // Reject all the pending changes for a record $record = GedcomRecord::getInstance(Filter::post('xref', WT_REGEX_XREF), $WT_TREE); if ($record && $record->canEdit() && Auth::isModerator($record->getTree())) { FlashMessages::addMessage(I18N::translate('The changes to “%s” have been rejected.', $record->getFullName())); FunctionsImport::rejectAllChanges($record); } else { http_response_code(406); } break; case 'theme': // Change the current theme $theme = Filter::post('theme'); if (Site::getPreference('ALLOW_USER_THEMES') && array_key_exists($theme, Theme::themeNames())) { Session::put('theme_id', $theme); // Remember our selection Auth::user()->setPreference('theme', $theme); } else { // Request for a non-existant theme. http_response_code(406); } break; }
foreach ($facts1 as $id1 => $fact1) { foreach ($facts2 as $id2 => $fact2) { if ($fact1->getFactId() === $fact2->getFactId()) { $facts[] = $fact1; unset($facts1[$id1]); unset($facts2[$id2]); } } } if ($rec1 && $rec2 && $rec1->getXref() !== $rec2->getXref() && $rec1::RECORD_TYPE === $rec2::RECORD_TYPE && Filter::post('action') === 'merge' && Filter::checkCsrf()) { // Use the XREF of the record. $gid1 = $rec1->getXref(); $gid2 = $rec2->getXref(); $ids = FunctionsDb::fetchAllLinks($gid2, $WT_TREE->getTreeId()); // If we are not auto-accepting, then we can show a link to the pending deletion if (Auth::user()->getPreference('auto_accept')) { $record2_name = $rec2->getFullName(); } else { $record2_name = '<a class="alert-link" href="' . $rec2->getHtmlUrl() . '">' . $rec2->getFullName() . '</a>'; } foreach ($ids as $id) { $record = GedcomRecord::getInstance($id, $WT_TREE); if (!$record->isPendingDeletion()) { FlashMessages::addMessage(I18N::translate('The link from “%1$s” to “%2$s” has been updated.', '<a class="alert-link" href="' . $record->getHtmlUrl() . '">' . $record->getFullName() . '</a>', $record2_name), 'info'); $gedcom = str_replace("@{$gid2}@", "@{$gid1}@", $record->getGedcom()); $gedcom = preg_replace('/(\\n1.*@.+@.*(?:(?:\\n[2-9].*)*))((?:\\n1.*(?:\\n[2-9].*)*)*\\1)/', '$2', $gedcom); $record->updateRecord($gedcom, true); } } // Update any linked user-accounts Database::prepare("UPDATE `##user_gedcom_setting`" . " SET setting_value=?" . " WHERE gedcom_id=? AND setting_name='gedcomid' AND setting_value=?")->execute(array($gid2, $WT_TREE->getTreeId(), $gid1));
/** * Delete this record */ public function deleteRecord() { // Create a pending change if (!$this->isPendingDeletion()) { Database::prepare("INSERT INTO `##change` (gedcom_id, xref, old_gedcom, new_gedcom, user_id) VALUES (?, ?, ?, '', ?)")->execute(array($this->tree->getTreeId(), $this->xref, $this->getGedcom(), Auth::id())); } // Auto-accept this pending change if (Auth::user()->getPreference('auto_accept')) { FunctionsImport::acceptAllChanges($this->xref, $this->tree->getTreeId()); } // Clear the cache self::$gedcom_record_cache = null; self::$pending_record_cache = null; Log::addEditLog('Delete: ' . static::RECORD_TYPE . ' ' . $this->xref); }
// but are submitted in POST so we can have long body text. $subject = Filter::post('subject', null, Filter::get('subject')); $body = Filter::post('body'); $from_name = Filter::post('from_name'); $from_email = Filter::post('from_email'); $action = Filter::post('action', 'compose|send', 'compose'); $to = Filter::post('to', null, Filter::get('to')); $method = Filter::post('method', 'messaging|messaging2|messaging3|mailto|none', Filter::get('method', 'messaging|messaging2|messaging3|mailto|none', 'messaging2')); $url = Filter::postUrl('url', Filter::getUrl('url')); $to_user = User::findByUserName($to); $controller = new SimpleController(); $controller->restrictAccess($to_user || Auth::isAdmin() && ($to === 'all' || $to === 'last_6mo' || $to === 'never_logged'))->setPageTitle(I18N::translate('webtrees message')); $errors = ''; // Is this message from a member or a visitor? if (Auth::check()) { $from = Auth::user()->getUserName(); } else { // Visitors must provide a valid email address if ($from_email && (!preg_match("/(.+)@(.+)/", $from_email, $match) || function_exists('checkdnsrr') && checkdnsrr($match[2]) === false)) { $errors .= '<p class="ui-state-error">' . I18N::translate('Please enter a valid email address.') . '</p>'; $action = 'compose'; } // Do not allow anonymous visitors to include links to external sites if (preg_match('/(?!' . preg_quote(WT_BASE_URL, '/') . ')(((?:ftp|http|https):\\/\\/)[a-zA-Z0-9.-]+)/', $subject . $body, $match)) { $errors .= '<p class="ui-state-error">' . I18N::translate('You are not allowed to send messages that contain external links.') . '</p>' . '<p class="ui-state-highlight">' . I18N::translate('You should delete the “%1$s” from “%2$s” and try again.', $match[2], $match[1]) . '</p>' . Log::addAuthenticationLog('Possible spam message from "' . $from_name . '"/"' . $from_email . '", subject="' . $subject . '", body="' . $body . '"'); $action = 'compose'; } $from = $from_email; } // Ensure the user always visits this page twice - once to compose it and again to send it. // This makes it harder for spammers.
/** * An HTML form to edit block settings * * @param int $block_id */ public function configureBlock($block_id) { global $WT_TREE, $controller; $PEDIGREE_ROOT_ID = $WT_TREE->getPreference('PEDIGREE_ROOT_ID'); $gedcomid = $WT_TREE->getUserPreference(Auth::user(), 'gedcomid'); if (Filter::postBool('save') && Filter::checkCsrf()) { $this->setBlockSetting($block_id, 'details', Filter::postBool('details')); $this->setBlockSetting($block_id, 'type', Filter::post('type', 'pedigree|descendants|hourglass|treenav', 'pedigree')); $this->setBlockSetting($block_id, 'pid', Filter::post('pid', WT_REGEX_XREF)); } $details = $this->getBlockSetting($block_id, 'details', '0'); $type = $this->getBlockSetting($block_id, 'type', 'pedigree'); $pid = $this->getBlockSetting($block_id, 'pid', Auth::check() ? $gedcomid ? $gedcomid : $PEDIGREE_ROOT_ID : $PEDIGREE_ROOT_ID); $controller->addExternalJavascript(WT_AUTOCOMPLETE_JS_URL)->addInlineJavascript('autocomplete();'); ?> <tr> <td class="descriptionbox wrap width33"><?php echo I18N::translate('Chart type'); ?> </td> <td class="optionbox"> <?php echo FunctionsEdit::selectEditControl('type', array('pedigree' => I18N::translate('Pedigree'), 'descendants' => I18N::translate('Descendants'), 'hourglass' => I18N::translate('Hourglass chart'), 'treenav' => I18N::translate('Interactive tree')), null, $type); ?> </td> </tr> <tr> <td class="descriptionbox wrap width33"><?php echo I18N::translate('Show details'); ?> </td> <td class="optionbox"> <?php echo FunctionsEdit::editFieldYesNo('details', $details); ?> </td> </tr> <tr> <td class="descriptionbox wrap width33"><?php echo I18N::translate('Individual'); ?> </td> <td class="optionbox"> <input data-autocomplete-type="INDI" type="text" name="pid" id="pid" value="<?php echo $pid; ?> " size="5"> <?php echo FunctionsPrint::printFindIndividualLink('pid'); $root = Individual::getInstance($pid, $WT_TREE); if ($root) { echo ' <span class="list_item">', $root->getFullName(), $root->formatFirstMajorFact(WT_EVENTS_BIRT, 1), '</span>'; } ?> </td> </tr> <?php }
if (!$user->checkPassword($password)) { Log::addAuthenticationLog('Login failed (incorrect password): ' . $username); throw new \Exception(I18N::translate('The username or password is incorrect.')); } if (!$user->getPreference('verified')) { Log::addAuthenticationLog('Login failed (not verified by user): ' . $username); throw new \Exception(I18N::translate('This account has not been verified. Please check your email for a verification message.')); } if (!$user->getPreference('verified_by_admin')) { Log::addAuthenticationLog('Login failed (not approved by admin): ' . $username); throw new \Exception(I18N::translate('This account has not been approved. Please wait for an administrator to approve it.')); } Auth::login($user); Log::addAuthenticationLog('Login: '******'/' . Auth::user()->getRealName()); Session::put('locale', Auth::user()->getPreference('language')); Session::put('theme_id', Auth::user()->getPreference('theme')); // We're logging in as an administrator if (Auth::isAdmin()) { // Check for updates $latest_version_txt = Functions::fetchLatestVersion(); if (preg_match('/^[0-9.]+\\|[0-9.]+\\|/', $latest_version_txt)) { list($latest_version, $earliest_version, $download_url) = explode('|', $latest_version_txt); if (version_compare(WT_VERSION, $latest_version) < 0) { FlashMessages::addMessage(I18N::translate('A new version of webtrees is available.') . ' <a href="admin_site_upgrade.php"><b>' . I18N::translate('Upgrade to webtrees %s.', '<span dir="ltr">' . $latest_version . '</span>') . '</b></a>'); } } } // Redirect to the target URL header('Location: ' . WT_BASE_URL . $url); return; } catch (\Exception $ex) {
// Total filtered/unfiltered rows $recordsFiltered = (int) Database::prepare("SELECT FOUND_ROWS()")->fetchOne(); $recordsTotal = (int) Database::prepare("SELECT COUNT(*) FROM `##change`")->fetchOne(); header('Content-type: application/json'); // See http://www.datatables.net/usage/server-side echo json_encode(array('draw' => Filter::getInteger('draw'), 'recordsTotal' => $recordsTotal, 'recordsFiltered' => $recordsFiltered, 'data' => $data)); return; } $controller->pageHeader()->addExternalJavascript(WT_JQUERY_DATATABLES_JS_URL)->addExternalJavascript(WT_DATATABLES_BOOTSTRAP_JS_URL)->addExternalJavascript(WT_MOMENT_JS_URL)->addExternalJavascript(WT_BOOTSTRAP_DATETIMEPICKER_JS_URL)->addInlineJavascript(' jQuery(".table-site-changes").dataTable( { processing: true, serverSide: true, ajax: "' . WT_BASE_URL . WT_SCRIPT_NAME . '?action=load_json&from=' . $from . '&to=' . $to . '&type=' . $type . '&oldged=' . rawurlencode($oldged) . '&newged=' . rawurlencode($newged) . '&xref=' . rawurlencode($xref) . '&user='******'&gedc=' . rawurlencode($gedc) . '", ' . I18N::datatablesI18N(array(10, 20, 50, 100, 500, 1000, -1)) . ', sorting: [[ 0, "desc" ]], pageLength: ' . Auth::user()->getPreference('admin_site_change_page_size', 10) . ', columns: [ /* change_id */ { visible: false }, /* Timestamp */ { sort: 0 }, /* Status */ { }, /* Record */ { }, /* Old data */ { sortable: false }, /* New data */ { sortable: false }, /* User */ { }, /* Family tree */ { } ] }); jQuery("#from,#to").parent("div").datetimepicker({ format: "YYYY-MM-DD", minDate: "' . $earliest . '", maxDate: "' . $latest . '",
/** * A link to the user's individual record. * * @return Menu|null */ protected function menuMyPedigree() { $gedcomid = $this->tree->getUserPreference(Auth::user(), 'gedcomid'); if ($gedcomid && Module::isActiveChart($this->tree, 'pedigree_chart')) { $showFull = $this->tree->getPreference('PEDIGREE_FULL_DETAILS') ? 1 : 0; $showLayout = $this->tree->getPreference('PEDIGREE_LAYOUT') ? 1 : 0; return new Menu(I18N::translate('My pedigree'), 'pedigree.php?' . $this->tree_url . '&rootid=' . $gedcomid . '&show_full=' . $showFull . '&talloffset=' . $showLayout, 'menu-mypedigree'); } else { return null; } }
?> <p class="small text-muted"> <?php echo I18N::translate('This checkbox controls your visibility to other users while you’re online. It also controls your ability to see other online users who are configured to be visible.<br><br>When this box is unchecked, you will be completely invisible to others, and you will also not be able to see other online users. When this box is checked, exactly the opposite is true. You will be visible to others, and you will also be able to see others who are configured to be visible.'); ?> </p> </div> </div> <div id="edituser_submit"> <input type="submit" value="<?php echo I18N::translate('save'); ?> "> </div> <?php if (!Auth::user()->getPreference('canadmin')) { ?> <a href="#" onclick="if (confirm('<?php echo I18N::translate('Are you sure you want to delete “%s”?', Filter::escapeJs(Auth::user()->getUserName())); ?> ')) {jQuery('#form_action').val('delete'); document.editform.submit(); }"> <?php echo I18N::translate('Delete your account'); ?> </a> <?php } ?> </form> </div> <?php
// We're logging in as an administrator if (Auth::isAdmin()) { // Check for updates $latest_version_txt = Functions::fetchLatestVersion(); if (preg_match('/^[0-9.]+\\|[0-9.]+\\|/', $latest_version_txt)) { list($latest_version, $earliest_version, $download_url) = explode('|', $latest_version_txt); if (version_compare(WT_VERSION, $latest_version) < 0) { FlashMessages::addMessage(I18N::translate('A new version of webtrees is available.') . ' <a href="admin_site_upgrade.php"><b>' . I18N::translate('Upgrade to webtrees %s.', '<span dir="ltr">' . $latest_version . '</span>') . '</b></a>'); } } } // If we were on a "home page", redirect to "my page" if ($url === '' || strpos($url, 'index.php?ctype=gedcom') === 0) { $url = 'index.php?ctype=user'; // Switch to a tree where we have a genealogy record (or keep to the current/default). $tree = Database::prepare("SELECT gedcom_name FROM `##gedcom` JOIN `##user_gedcom_setting` USING (gedcom_id)" . " WHERE setting_name = 'gedcomid' AND user_id = :user_id")->execute(array('user_id' => Auth::user()->getUserId()))->fetchOne(); $url .= '&ged=' . Filter::escapeUrl($tree); } // Redirect to the target URL header('Location: ' . WT_BASE_URL . $url); return; } catch (\Exception $ex) { $message = $ex->getMessage(); } // No break; // No break; default: $controller->setPageTitle(I18N::translate('Login'))->pageHeader()->addInlineJavascript(' jQuery("#new_passwd_form").hide(); jQuery("#passwd_click").click(function() { jQuery("#new_passwd_form").slideToggle(100, function() {
/** * Create a header for a (newly-created or already-imported) gedcom file. * * @param Tree $tree * * @return string */ public static function gedcomHeader(Tree $tree) { // Default values for a new header $HEAD = "0 HEAD"; $SOUR = "\n1 SOUR " . WT_WEBTREES . "\n2 NAME " . WT_WEBTREES . "\n2 VERS " . WT_VERSION; $DEST = "\n1 DEST DISKETTE"; $DATE = "\n1 DATE " . strtoupper(date("d M Y")) . "\n2 TIME " . date("H:i:s"); $GEDC = "\n1 GEDC\n2 VERS 5.5.1\n2 FORM Lineage-Linked"; $CHAR = "\n1 CHAR UTF-8"; $FILE = "\n1 FILE " . $tree->getName(); $LANG = ""; $PLAC = "\n1 PLAC\n2 FORM City, County, State/Province, Country"; $COPR = ""; $SUBN = ""; $SUBM = "\n1 SUBM @SUBM@\n0 @SUBM@ SUBM\n1 NAME " . Auth::user()->getUserName(); // The SUBM record is mandatory // Preserve some values from the original header $record = GedcomRecord::getInstance('HEAD', $tree); if ($fact = $record->getFirstFact('PLAC')) { $PLAC = "\n1 PLAC\n2 FORM " . $fact->getAttribute('FORM'); } if ($fact = $record->getFirstFact('LANG')) { $LANG = $fact->getValue(); } if ($fact = $record->getFirstFact('SUBN')) { $SUBN = $fact->getValue(); } if ($fact = $record->getFirstFact('COPR')) { $COPR = $fact->getValue(); } // Link to actual SUBM/SUBN records, if they exist $subn = Database::prepare("SELECT o_id FROM `##other` WHERE o_type=? AND o_file=?")->execute(array('SUBN', $tree->getTreeId()))->fetchOne(); if ($subn) { $SUBN = "\n1 SUBN @{$subn}@"; } $subm = Database::prepare("SELECT o_id FROM `##other` WHERE o_type=? AND o_file=?")->execute(array('SUBM', $tree->getTreeId()))->fetchOne(); if ($subm) { $SUBM = "\n1 SUBM @{$subm}@"; } return $HEAD . $SOUR . $DEST . $DATE . $GEDC . $CHAR . $FILE . $COPR . $LANG . $PLAC . $SUBN . $SUBM . "\n"; }
/** * Get significant information from this page, to allow other pages such as * charts and reports to initialise with the same records * * @return Individual */ public function getSignificantIndividual() { global $WT_TREE; static $individual; // Only query the DB once. if (!$individual && $WT_TREE->getUserPreference(Auth::user(), 'rootid')) { $individual = Individual::getInstance($WT_TREE->getUserPreference(Auth::user(), 'rootid'), $WT_TREE); } if (!$individual && $WT_TREE->getUserPreference(Auth::user(), 'gedcomid')) { $individual = Individual::getInstance($WT_TREE->getUserPreference(Auth::user(), 'gedcomid'), $WT_TREE); } if (!$individual) { $individual = Individual::getInstance($WT_TREE->getPreference('PEDIGREE_ROOT_ID'), $WT_TREE); } if (!$individual) { $individual = Individual::getInstance(Database::prepare("SELECT MIN(i_id) FROM `##individuals` WHERE i_file=?")->execute(array($WT_TREE->getTreeId()))->fetchOne(), $WT_TREE); } if (!$individual) { // always return a record $individual = new Individual('I', '0 @I@ INDI', null, $WT_TREE); } return $individual; }
$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, serverSide: true, ajax: { "url": "' . WT_SCRIPT_NAME . '?action=load_json", "type": "POST" }, search: { search: "' . Filter::escapeJs(Filter::get('filter')) . '" }, autoWidth: false, pageLength: ' . Auth::user()->getPreference('admin_users_page_size', 10) . ', sorting: [[2, "asc"]], columns: [ /* details */ { sortable: false }, /* user-id */ { visible: false }, /* user_name */ null, /* real_name */ null, /* email */ null, /* language */ null, /* registered (sort) */ { visible: false }, /* registered */ { dataSort: 7 }, /* last_login (sort) */ { visible: false }, /* last_login */ { dataSort: 9 }, /* verified */ null, /* approved */ null ]
/** * 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" * * @return string */ public function generateFanChart($what) { $treeid = $this->sosaAncestors($this->generations); $fanw = 640 * $this->fan_width / 100; $fandeg = 90 * $this->fan_style; $html = ''; $treesize = count($treeid) + 1; // 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(Theme::theme()->parameter('chart-font-color'), 0, 2)), hexdec(substr(Theme::theme()->parameter('chart-font-color'), 2, 2)), hexdec(substr(Theme::theme()->parameter('chart-font-color'), 4, 2))); $bgcolor = ImageColorAllocate($image, hexdec(substr(Theme::theme()->parameter('chart-background-u'), 0, 2)), hexdec(substr(Theme::theme()->parameter('chart-background-u'), 2, 2)), hexdec(substr(Theme::theme()->parameter('chart-background-u'), 4, 2))); $bgcolorM = ImageColorAllocate($image, hexdec(substr(Theme::theme()->parameter('chart-background-m'), 0, 2)), hexdec(substr(Theme::theme()->parameter('chart-background-m'), 2, 2)), hexdec(substr(Theme::theme()->parameter('chart-background-m'), 4, 2))); $bgcolorF = ImageColorAllocate($image, hexdec(substr(Theme::theme()->parameter('chart-background-f'), 0, 2)), hexdec(substr(Theme::theme()->parameter('chart-background-f'), 2, 2)), hexdec(substr(Theme::theme()->parameter('chart-background-f'), 4, 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) { $person = $treeid[$sosa]; if ($person) { $name = $person->getFullName(); $addname = $person->getAddName(); $text = I18N::reverseText($name); if ($addname) { $text .= "\n" . I18N::reverseText($addname); } $text .= "\n" . I18N::reverseText($person->getLifeSpan()); switch ($person->getSex()) { case 'M': $bg = $bgcolorM; break; case 'F': $bg = $bgcolorF; break; default: $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 / Theme::theme()->parameter('chart-font-size') * $scale); $wmax = min($wmax, 35 * $scale); if ($gen == 0) { $wmax = min($wmax, 17 * $scale); } $text = $this->splitAlignText($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, Theme::theme()->parameter('chart-font-size'), $tangle, $tx, $ty, $color, Theme::theme()->parameter('chart-font-name'), $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 $pid = $person->getXref(); $imagemap .= '" href="#' . $pid . '"'; $tempURL = 'fanchart.php?rootid=' . $pid . '&generations=' . $this->generations . '&fan_width=' . $this->fan_width . '&fan_style=' . $this->fan_style . '&ged=' . $person->getTree()->getNameUrl(); $html .= '<div id="' . $pid . '" class="fan_chart_menu">'; $html .= '<div class="person_box"><div class="details1">'; $html .= '<a href="' . $person->getHtmlUrl() . '" class="name1">' . $name; if ($addname) { $html .= $addname; } $html .= '</a>'; $html .= '<ul class="charts">'; $html .= '<li><a href="pedigree.php?rootid=' . $pid . '&ged=' . $person->getTree()->getNameUrl() . '" >' . I18N::translate('Pedigree') . '</a></li>'; if (Module::getModuleByName('googlemap')) { $html .= '<li><a href="module.php?mod=googlemap&mod_action=pedigree_map&rootid=' . $pid . '&ged=' . $person->getTree()->getNameUrl() . '">' . I18N::translate('Pedigree map') . '</a></li>'; } $gedcomid = $person->getTree()->getUserPreference(Auth::user(), 'gedcomid'); if ($gedcomid && $gedcomid != $pid) { $html .= '<li><a href="relationship.php?pid1=' . $gedcomid . '&pid2=' . $pid . '&ged=' . $person->getTree()->getNameUrl() . '">' . I18N::translate('Relationship to me') . '</a></li>'; } $html .= '<li><a href="descendancy.php?rootid=' . $pid . '&ged=' . $person->getTree()->getNameUrl() . '" >' . I18N::translate('Descendants') . '</a></li>'; $html .= '<li><a href="ancestry.php?rootid=' . $pid . '&ged=' . $person->getTree()->getNameUrl() . '">' . I18N::translate('Ancestors') . '</a></li>'; $html .= '<li><a href="compact.php?rootid=' . $pid . '&ged=' . $person->getTree()->getNameUrl() . '">' . I18N::translate('Compact tree') . '</a></li>'; $html .= '<li><a href="' . $tempURL . '">' . I18N::translate('Fan chart') . '</a></li>'; $html .= '<li><a href="hourglass.php?rootid=' . $pid . '&ged=' . $person->getTree()->getNameUrl() . '">' . I18N::translate('Hourglass chart') . '</a></li>'; if (Module::getModuleByName('tree')) { $html .= '<li><a href="module.php?mod=tree&mod_action=treeview&ged=' . $person->getTree()->getNameUrl() . '&rootid=' . $pid . '">' . I18N::translate('Interactive tree') . '</a></li>'; } $html .= '</ul>'; // spouse(s) and children foreach ($person->getSpouseFamilies() as $family) { $spouse = $family->getSpouse($person); if ($spouse) { $html .= '<a href="' . $spouse->getHtmlUrl() . '" class="name1">' . $spouse->getFullName() . '</a>'; $kids = $family->getChildren(); if ($kids) { $html .= '<ul class="children">'; foreach ($kids as $child) { $html .= '<li><a href="' . $child->getHtmlUrl() . '" class="name1">' . $child->getFullName() . '</a></li>'; } $html .= '</ul>'; } } } // siblings foreach ($person->getChildFamilies() as $family) { $children = $family->getChildren(); if ($children) { $html .= '<div class="name1">'; // With two children in a family, you have only one sibling. $html .= count($children) > 2 ? I18N::translate('Siblings') : I18N::translate('Sibling'); $html .= '</div>'; $html .= '<ul class="siblings">'; foreach ($children as $sibling) { if ($sibling !== $person) { $html .= '<li><a href="' . $sibling->getHtmlUrl() . '" class="name1"> ' . $sibling->getFullName() . '</a></li>'; } } $html .= '</ul>'; } } $html .= '</div></div>'; $html .= '</div>'; $imagemap .= ' alt="' . strip_tags($person->getFullName()) . '" title="' . strip_tags($person->getFullName()) . '">'; } $deg1 -= $angle; $deg2 -= $angle; $sosa--; } $rx -= $rw; $gen--; } $imagemap .= '</map>'; switch ($what) { case 'html': return $html . $imagemap . '<div id="fan_chart_img"><img src="' . WT_SCRIPT_NAME . '?rootid=' . $this->root->getXref() . '&fan_style=' . $this->fan_style . '&generations=' . $this->generations . '&fan_width=' . $this->fan_width . '&img=1" width="' . $fanw . '" height="' . $fanh . '" alt="' . strip_tags($this->getPageTitle()) . '" usemap="#fanmap"></div>'; case 'png': ImageStringUp($image, 1, $fanw - 10, $fanh / 3, WT_BASE_URL, $color); ob_start(); ImagePng($image); ImageDestroy($image); return ob_get_clean(); default: throw new \InvalidArgumentException(__METHOD__ . ' ' . $what); } }
/** * 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 $controller; $id = $this->getName() . $block_id; $class = $this->getName() . '_block'; $controller->addInlineJavascript(' jQuery("#new_passwd").hide(); jQuery("#passwd_click").click(function() { jQuery("#new_passwd").slideToggle(100, function() { jQuery("#new_passwd_username").focus(); }); return false; }); '); if (Auth::check()) { $title = I18N::translate('Logout'); $content = '<div class="center"><form method="post" action="logout.php" name="logoutform" onsubmit="return true;">'; $content .= '<br><a href="../../edituser.php" class="name2">' . I18N::translate('Logged in as ') . ' ' . Auth::user()->getRealNameHtml() . '</a><br><br>'; $content .= '<input type="submit" value="' . I18N::translate('Logout') . '">'; $content .= '<br><br></form></div>'; } else { $title = I18N::translate('Login'); $content = '<div id="login-box"> <form id="login-form" name="login-form" method="post" action="' . WT_LOGIN_URL . '"> <input type="hidden" name="action" value="login">'; $content .= '<div> <label for="username">' . I18N::translate('Username') . '<input type="text" id="username" name="username" class="formField"> </label> </div> <div> <label for="password">' . I18N::translate('Password') . '<input type="password" id="password" name="password" class="formField"> </label> </div> <div> <input type="submit" value="' . I18N::translate('Login') . '"> </div> <div> <a href="#" id="passwd_click">' . I18N::translate('Request new password') . '</a> </div>'; if (Site::getPreference('USE_REGISTRATION_MODULE')) { $content .= '<div><a href="' . WT_LOGIN_URL . '?action=register">' . I18N::translate('Request new user account') . '</a></div>'; } $content .= '</form>'; // close "login-form" // hidden New Password block $content .= '<div id="new_passwd"> <form id="new_passwd_form" name="new_passwd_form" action="' . WT_LOGIN_URL . '" method="post"> <input type="hidden" name="time" value=""> <input type="hidden" name="action" value="requestpw"> <h4>' . I18N::translate('Lost password request') . '</h4> <div> <label for="new_passwd_username">' . I18N::translate('Username or email address') . '<input type="text" id="new_passwd_username" name="new_passwd_username" value=""> </label> </div> <div><input type="submit" value="' . I18N::translate('continue') . '"></div> </form> </div>'; //"new_passwd" $content .= '</div>'; //"login-box" } if ($template) { return Theme::theme()->formatBlock($id, $title, $class, $content); } else { return $content; } }
/** * Create a new record from GEDCOM data. * * @param string $gedcom * * @throws \Exception * * @return GedcomRecord */ public function createRecord($gedcom) { if (preg_match('/^0 @(' . WT_REGEX_XREF . ')@ (' . WT_REGEX_TAG . ')/', $gedcom, $match)) { $xref = $match[1]; $type = $match[2]; } else { throw new \Exception('Invalid argument to GedcomRecord::createRecord(' . $gedcom . ')'); } if (strpos("\r", $gedcom) !== false) { // MSDOS line endings will break things in horrible ways throw new \Exception('Evil line endings found in GedcomRecord::createRecord(' . $gedcom . ')'); } // webtrees creates XREFs containing digits. Anything else (e.g. “new”) is just a placeholder. if (!preg_match('/\\d/', $xref)) { $xref = $this->getNewXref($type); $gedcom = preg_replace('/^0 @(' . WT_REGEX_XREF . ')@/', '0 @' . $xref . '@', $gedcom); } // Create a change record, if not already present if (!preg_match('/\\n1 CHAN/', $gedcom)) { $gedcom .= "\n1 CHAN\n2 DATE " . date('d M Y') . "\n3 TIME " . date('H:i:s') . "\n2 _WT_USER " . Auth::user()->getUserName(); } // Create a pending change Database::prepare("INSERT INTO `##change` (gedcom_id, xref, old_gedcom, new_gedcom, user_id) VALUES (?, ?, '', ?, ?)")->execute(array($this->tree_id, $xref, $gedcom, Auth::id())); Log::addEditLog('Create: ' . $type . ' ' . $xref); // Accept this pending change if (Auth::user()->getPreference('auto_accept')) { FunctionsImport::acceptAllChanges($xref, $this->tree_id); } // Return the newly created record. Note that since GedcomRecord // has a cache of pending changes, we cannot use it to create a // record with a newly created pending change. return GedcomRecord::getInstance($xref, $this, $gedcom); }