/** * 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'; } }
/** * Startup activity */ public function __construct() { global $WT_TREE; parent::__construct(); $this->setPageTitle(I18N::translate('Lifespans')); $this->facts = explode('|', WT_EVENTS_BIRT . '|' . WT_EVENTS_DEAT . '|' . WT_EVENTS_MARR . '|' . WT_EVENTS_DIV); $tmp = explode('\\', get_class(I18N::defaultCalendar())); $cal = strtolower(array_pop($tmp)); $this->defaultCalendar = str_replace('calendar', '', $cal); $filterPids = false; // Request parameters $clear = Filter::getBool('clear'); $newpid = Filter::get('newpid', WT_REGEX_XREF); $addfam = Filter::getBool('addFamily'); $this->place = Filter::get('place'); $this->beginYear = Filter::getInteger('beginYear', 0, PHP_INT_MAX, null); $this->endYear = Filter::getInteger('endYear', 0, PHP_INT_MAX, null); $this->calendar = Filter::get('calendar', null, $this->defaultCalendar); $this->strictDate = Filter::getBool('strictDate'); // Set up base color parameters $this->colors['M'] = new ColorGenerator(240, self::SATURATION, self::LIGHTNESS, self::ALPHA, self::RANGE * -1); $this->colors['F'] = new ColorGenerator(00, self::SATURATION, self::LIGHTNESS, self::ALPHA, self::RANGE); // Build a list of people based on the input parameters if ($clear) { // Empty list & reset form $xrefs = array(); $this->place = null; $this->beginYear = null; $this->endYear = null; $this->calendar = $this->defaultCalendar; } elseif ($this->place) { // Get all individual & family records found for a place $this->place_obj = new Place($this->place, $WT_TREE); $xrefs = Database::prepare("SELECT DISTINCT `i_id` FROM `##placelinks`" . " JOIN `##individuals` ON `pl_gid`=`i_id` AND `pl_file`=`i_file`" . " WHERE `i_file`=:tree_id" . " AND `pl_p_id`=:place_id" . " UNION" . " SELECT DISTINCT `f_id` FROM `##placelinks`" . " JOIN `##families` ON `pl_gid`=`f_id` AND `pl_file`=`f_file`" . " WHERE `f_file`=:tree_id" . " AND `pl_p_id`=:place_id")->execute(array('tree_id' => $WT_TREE->getTreeId(), 'place_id' => $this->place_obj->getPlaceId()))->fetchOneColumn(); } else { // Modify an existing list of records $xrefs = Session::get(self::SESSION_DATA, array()); if ($newpid) { $xrefs = array_merge($xrefs, $this->addFamily(Individual::getInstance($newpid, $WT_TREE), $addfam)); $xrefs = array_unique($xrefs); } elseif (!$xrefs) { $xrefs = $this->addFamily($this->getSignificantIndividual(), false); } } $tmp = $this->getCalendarDate(unixtojd()); $this->currentYear = $tmp->today()->y; $tmp = strtoupper(strtr($this->calendar, array('jewish' => 'hebrew', 'french' => 'french r'))); $this->calendarEscape = sprintf('@#D%s@', $tmp); if ($xrefs) { // ensure date ranges are valid in preparation for filtering list if ($this->beginYear || $this->endYear) { $filterPids = true; if (!$this->beginYear) { $tmp = new Date($this->calendarEscape . ' 1'); $this->beginYear = $tmp->minimumDate()->y; } if (!$this->endYear) { $this->endYear = $this->currentYear; } $this->startDate = new Date($this->calendarEscape . $this->beginYear); $this->endDate = new Date($this->calendarEscape . $this->endYear); } // Test each xref to see if the search criteria are met foreach ($xrefs as $key => $xref) { $valid = false; $person = Individual::getInstance($xref, $WT_TREE); if ($person) { if ($person->canShow()) { foreach ($person->getFacts() as $fact) { if ($this->checkFact($fact)) { $this->people[] = $person; $valid = true; break; } } } } else { $family = Family::getInstance($xref, $WT_TREE); if ($family && $family->canShow() && $this->checkFact($family->getMarriage())) { $valid = true; $this->people[] = $family->getHusband(); $this->people[] = $family->getWife(); } } if (!$valid) { unset($xrefs[$key]); // no point in storing a xref if we can't use it } } Session::put(self::SESSION_DATA, $xrefs); } else { Session::forget(self::SESSION_DATA); } $this->people = array_filter(array_unique($this->people)); $count = count($this->people); if ($count) { // Build the subtitle if ($this->place && $filterPids) { $this->subtitle = I18N::plural('%s individual with events in %s between %s and %s', '%s individuals with events in %s between %s and %s', $count, I18N::number($count), $this->place, $this->startDate->display(false, '%Y'), $this->endDate->display(false, '%Y')); } elseif ($this->place) { $this->subtitle = I18N::plural('%s individual with events in %s', '%s individuals with events in %s', $count, I18N::number($count), $this->place); } elseif ($filterPids) { $this->subtitle = I18N::plural('%s individual with events between %s and %s', '%s individuals with events between %s and %s', $count, I18N::number($count), $this->startDate->display(false, '%Y'), $this->endDate->display(false, '%Y')); } else { $this->subtitle = I18N::plural('%s individual', '%s individuals', $count, I18N::number($count)); } // Sort the array in order of birth year usort($this->people, function (Individual $a, Individual $b) { return Date::compare($a->getEstimatedBirthDate(), $b->getEstimatedBirthDate()); }); //Find the mimimum birth year and maximum death year from the individuals in the array. $bdate = $this->getCalendarDate($this->people[0]->getEstimatedBirthDate()->minimumJulianDay()); $minyear = $bdate->y; $that = $this; // PHP5.3 cannot access $this inside a closure $maxyear = array_reduce($this->people, function ($carry, Individual $item) use($that) { $date = $that->getCalendarDate($item->getEstimatedDeathDate()->maximumJulianDay()); return max($carry, $date->y); }, 0); } elseif ($filterPids) { $minyear = $this->endYear; $maxyear = $this->endYear; } else { $minyear = $this->currentYear; $maxyear = $this->currentYear; } $maxyear = min($maxyear, $this->currentYear); // Limit maximum year to current year as we can't forecast the future $minyear = min($minyear, $maxyear - $WT_TREE->getPreference('MAX_ALIVE_AGE')); // Set default minimum chart length $this->timelineMinYear = (int) floor($minyear / 10) * 10; // round down to start of the decade $this->timelineMaxYear = (int) ceil($maxyear / 10) * 10; // round up to start of next decade }
} } } } } 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; }
/** {@inheritdoc} */ public function getSidebarAjaxContent() { global $WT_TREE; $cart = Session::get('cart'); $clip_ctrl = new ClippingsCartController(); $add = Filter::get('add', WT_REGEX_XREF); $add1 = Filter::get('add1', WT_REGEX_XREF); $remove = Filter::get('remove', WT_REGEX_XREF); $others = Filter::get('others'); $clip_ctrl->level1 = Filter::getInteger('level1'); $clip_ctrl->level2 = Filter::getInteger('level2'); $clip_ctrl->level3 = Filter::getInteger('level3'); if ($add) { $record = GedcomRecord::getInstance($add, $WT_TREE); if ($record) { $clip_ctrl->id = $record->getXref(); $clip_ctrl->type = $record::RECORD_TYPE; $clip_ctrl->addClipping($record); } } elseif ($add1) { $record = Individual::getInstance($add1, $WT_TREE); if ($record) { $clip_ctrl->id = $record->getXref(); $clip_ctrl->type = $record::RECORD_TYPE; if ($others == 'parents') { foreach ($record->getChildFamilies() as $family) { $clip_ctrl->addClipping($family); $clip_ctrl->addFamilyMembers($family); } } elseif ($others == 'ancestors') { $clip_ctrl->addAncestorsToCart($record, $clip_ctrl->level1); } elseif ($others == 'ancestorsfamilies') { $clip_ctrl->addAncestorsToCartFamilies($record, $clip_ctrl->level2); } elseif ($others == 'members') { foreach ($record->getSpouseFamilies() as $family) { $clip_ctrl->addClipping($family); $clip_ctrl->addFamilyMembers($family); } } elseif ($others == 'descendants') { foreach ($record->getSpouseFamilies() as $family) { $clip_ctrl->addClipping($family); $clip_ctrl->addFamilyDescendancy($family, $clip_ctrl->level3); } } } } elseif ($remove) { unset($cart[$WT_TREE->getTreeId()][$remove]); Session::put('cart', $cart); } elseif (isset($_REQUEST['empty'])) { $cart[$WT_TREE->getTreeId()] = array(); Session::put('cart', $cart); } elseif (isset($_REQUEST['download'])) { return $this->downloadForm($clip_ctrl); } return $this->getCartList(); }
// Send user message by email only Mail::send($WT_TREE, $mail2_to, $mail2_to, $mail2_from, $mail2_from, $mail2_subject, $mail2_body); // Send admin message by email and/or internal messaging Mail::send($WT_TREE, $webmaster->getEmail(), $webmaster->getRealName(), $user->getEmail(), $user->getRealName(), $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->getEmail(), WT_CLIENT_IP, $webmaster->getUserId(), $mail1_subject, Filter::unescapeHtml($mail1_body))); } echo '<div class="confirm"><p>', I18N::translate('Hello %s…<br>Thank you for your registration.', $user->getRealNameHtml()), '</p>'; echo '<p>', I18N::translate('We will now send a confirmation email to the address <b>%s</b>. You must verify your account request by following instructions in the confirmation email. If you do not confirm your account request within seven days, your application will be rejected automatically. You will have to apply again.<br><br>After you have followed the instructions in the confirmation email, the administrator still has to approve your request before your account can be used.<br><br>To login to this website, you will need to know your user name and password.', $user->getEmail()), '</p>'; echo '</div>'; echo '</div>'; return; } } Session::put('good_to_send', true); $controller->pageHeader()->addInlineJavascript('function regex_quote(str) {return str.replace(/[\\\\.?+*()[\\](){}|]/g, "\\\\$&");}'); ?> <div id="login-register-page"> <h2><?php echo $controller->getPageTitle(); ?> </h2> <?php if (Site::getPreference('SHOW_REGISTER_CAUTION')) { ?> <div id="register-text"> <?php echo I18N::translate('<div class="largeError">Notice:</div><div class="error">By completing and submitting this form, you agree:<ul><li>to protect the privacy of living individuals listed on our site;</li><li>and in the text box below, to explain to whom you are related, or to provide us with information on someone who should be listed on our website.</li></ul></div>'); ?>
/** * Cross-Site Request Forgery tokens - ensure that the user is submitting * a form that was generated by the current session. * * @return string */ public static function getCsrfToken() { if (!Session::has('CSRF_TOKEN')) { $charset = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcedfghijklmnopqrstuvwxyz0123456789'; $csrf_token = ''; for ($n = 0; $n < 32; ++$n) { $csrf_token .= substr($charset, mt_rand(0, 61), 1); } Session::put('CSRF_TOKEN', $csrf_token); } return Session::get('CSRF_TOKEN'); }
/** * 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); }