/** * Create the chart controller * * @param int $show_full needed for use by charts module */ public function __construct($show_full = 1) { global $WT_TREE; parent::__construct(); $rootid = Filter::get('rootid', WT_REGEX_XREF); $this->root = Individual::getInstance($rootid, $WT_TREE); if (!$this->root) { // Missing root individual? Show the chart for someone. $this->root = $this->getSignificantIndividual(); } if (!$this->root || !$this->root->canShowName()) { http_response_code(404); $this->error_message = I18N::translate('This individual does not exist or you do not have permission to view it.'); } // Extract parameter from form if ($show_full) { $this->show_full = Filter::getInteger('show_full', 0, 1, $WT_TREE->getPreference('PEDIGREE_FULL_DETAILS')); } else { $this->show_full = 0; } $this->box = new \stdClass(); if ($this->showFull()) { $this->box->width = Theme::theme()->parameter('chart-box-x'); $this->box->height = Theme::theme()->parameter('chart-box-y'); } else { $this->box->width = Theme::theme()->parameter('compact-chart-box-x'); $this->box->height = Theme::theme()->parameter('compact-chart-box-y'); } }
/** * {@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); }
/** * 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; switch (Filter::get('action')) { case 'deletenews': $news_id = Filter::get('news_id'); if ($news_id) { Database::prepare("DELETE FROM `##news` WHERE news_id = ?")->execute(array($news_id)); } break; } $more_news = Filter::getInteger('more_news'); $limit = 5 * (1 + $more_news); $articles = Database::prepare("SELECT SQL_CACHE news_id, user_id, gedcom_id, UNIX_TIMESTAMP(updated) + :offset AS updated, subject, body FROM `##news` WHERE gedcom_id = :tree_id ORDER BY updated DESC LIMIT :limit")->execute(array('offset' => WT_TIMESTAMP_OFFSET, 'tree_id' => $WT_TREE->getTreeId(), 'limit' => $limit))->fetchAll(); $count = Database::prepare("SELECT SQL_CACHE COUNT(*) FROM `##news` WHERE gedcom_id = :tree_id")->execute(array('tree_id' => $WT_TREE->getTreeId()))->fetchOne(); $id = $this->getName() . $block_id; $class = $this->getName() . '_block'; $title = $this->getTitle(); $content = ''; if (empty($articles)) { $content .= I18N::translate('No news articles have been submitted.'); } foreach ($articles as $article) { $content .= '<div class="news_box">'; $content .= '<div class="news_title">' . Filter::escapeHtml($article->subject) . '</div>'; $content .= '<div class="news_date">' . FunctionsDate::formatTimestamp($article->updated) . '</div>'; if ($article->body == strip_tags($article->body)) { $article->body = nl2br($article->body, false); } $content .= $article->body; if (Auth::isManager($WT_TREE)) { $content .= '<hr>'; $content .= '<a href="#" onclick="window.open(\'editnews.php?news_id=\'+' . $article->news_id . ', \'_blank\', news_window_specs); return false;">' . I18N::translate('Edit') . '</a>'; $content .= ' | '; $content .= '<a href="index.php?action=deletenews&news_id=' . $article->news_id . '&ctype=' . $ctype . '&ged=' . $WT_TREE->getNameHtml() . '" onclick="return confirm(\'' . I18N::translate('Are you sure you want to delete “%s”?', Filter::escapeHtml($article->subject)) . "');\">" . I18N::translate('Delete') . '</a><br>'; } $content .= '</div>'; } if (Auth::isManager($WT_TREE)) { $content .= '<a href="#" onclick="window.open(\'editnews.php?gedcom_id=' . $WT_TREE->getTreeId() . '\', \'_blank\', news_window_specs); return false;">' . I18N::translate('Add a news article') . '</a>'; } if ($count > $limit) { if (Auth::isManager($WT_TREE)) { $content .= ' | '; } $content .= '<a href="#" onclick="jQuery(\'#' . $id . '\').load(\'index.php?ctype=gedcom&ged=' . $WT_TREE->getNameUrl() . '&block_id=' . $block_id . '&action=ajax&more_news=' . ($more_news + 1) . '\'); return false;">' . I18N::translate('More news articles') . "</a>"; } if ($template) { return Theme::theme()->formatBlock($id, $title, $class, $content); } else { return $content; } }
/** * Create the descendancy controller */ public function __construct() { global $WT_TREE; parent::__construct(); // Extract parameters from form $this->chart_style = Filter::getInteger('chart_style', 0, 3, 0); $this->generations = Filter::getInteger('generations', 2, $WT_TREE->getPreference('MAX_DESCENDANCY_GENERATIONS'), $WT_TREE->getPreference('DEFAULT_PEDIGREE_GENERATIONS')); if ($this->root && $this->root->canShowName()) { $this->setPageTitle(I18N::translate('Descendants of %s', $this->root->getFullName())); } else { $this->setPageTitle(I18N::translate('Descendants')); } }
/** * Startup activity */ public function __construct() { global $WT_TREE; parent::__construct(); // Extract form parameters $this->show_cousins = Filter::getInteger('show_cousins', 0, 1); $this->chart_style = Filter::getInteger('chart_style', 0, 3); $this->generations = Filter::getInteger('PEDIGREE_GENERATIONS', 2, $WT_TREE->getPreference('MAX_PEDIGREE_GENERATIONS'), $WT_TREE->getPreference('DEFAULT_PEDIGREE_GENERATIONS')); if ($this->root && $this->root->canShowName()) { $this->setPageTitle(I18N::translate('Ancestors of %s', $this->root->getFullName())); } else { $this->setPageTitle(I18N::translate('Ancestors')); } }
/** * 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; switch (Filter::get('action')) { case 'deletenews': $news_id = Filter::getInteger('news_id'); if ($news_id) { Database::prepare("DELETE FROM `##news` WHERE news_id = ?")->execute(array($news_id)); } break; } $block = $this->getBlockSetting($block_id, 'block', '1'); foreach (array('block') as $name) { if (array_key_exists($name, $cfg)) { ${$name} = $cfg[$name]; } } $usernews = Database::prepare("SELECT SQL_CACHE news_id, user_id, gedcom_id, UNIX_TIMESTAMP(updated) AS updated, subject, body FROM `##news` WHERE user_id = ? ORDER BY updated DESC")->execute(array(Auth::id()))->fetchAll(); $id = $this->getName() . $block_id; $class = $this->getName() . '_block'; $title = ''; $title .= $this->getTitle(); $content = ''; if (!$usernews) { $content .= I18N::translate('You have not created any journal items.'); } foreach ($usernews as $news) { $content .= '<div class="journal_box">'; $content .= '<div class="news_title">' . $news->subject . '</div>'; $content .= '<div class="news_date">' . FunctionsDate::formatTimestamp($news->updated) . '</div>'; if ($news->body == strip_tags($news->body)) { // No HTML? $news->body = nl2br($news->body, false); } $content .= $news->body . '<br><br>'; $content .= '<a href="#" onclick="window.open(\'editnews.php?news_id=\'+' . $news->news_id . ', \'_blank\', indx_window_specs); return false;">' . I18N::translate('Edit') . '</a> | '; $content .= '<a href="index.php?action=deletenews&news_id=' . $news->news_id . '&ctype=' . $ctype . '&ged=' . $WT_TREE->getNameHtml() . '" onclick="return confirm(\'' . I18N::translate('Are you sure you want to delete “%s”?', Filter::escapeHtml($news->subject)) . "');\">" . I18N::translate('Delete') . '</a><br>'; $content .= "</div><br>"; } $content .= '<br><a href="#" onclick="window.open(\'editnews.php?user_id=' . Auth::id() . '\', \'_blank\', indx_window_specs); return false;">' . I18N::translate('Add a new journal entry') . '</a>'; if ($template) { if ($block) { $class .= ' small_inner_block'; } return Theme::theme()->formatBlock($id, $title, $class, $content); } else { return $content; } }
/** * Create the controller */ public function __construct() { global $WT_TREE; parent::__construct(); $default_generations = $WT_TREE->getPreference('DEFAULT_PEDIGREE_GENERATIONS'); // Extract the request parameters $this->fan_style = Filter::getInteger('fan_style', 2, 4, 3); $this->fan_width = Filter::getInteger('fan_width', 50, 500, 100); $this->generations = Filter::getInteger('generations', 2, 9, $default_generations); if ($this->root && $this->root->canShowName()) { $this->setPageTitle(I18N::translate('Fan chart of %s', $this->root->getFullName())); } else { $this->setPageTitle(I18N::translate('Fan chart')); } }
/** * Create a family-book controller */ public function __construct() { global $WT_TREE; parent::__construct(); // Extract the request parameters $this->show_spouse = Filter::getInteger('show_spouse', 0, 1); $this->descent = Filter::getInteger('descent', 0, 9, 5); $this->generations = Filter::getInteger('generations', 2, $WT_TREE->getPreference('MAX_DESCENDANCY_GENERATIONS'), 2); $this->bhalfheight = $this->getBoxDimensions()->height / 2; if ($this->root && $this->root->canShowName()) { $this->setPageTitle(I18N::translate('Family book of %s', $this->root->getFullName())); } else { $this->setPageTitle(I18N::translate('Family book')); } //Checks how many generations of descendency is for the person for formatting purposes $this->dgenerations = $this->maxDescendencyGenerations($this->root->getXref(), 0); if ($this->dgenerations < 1) { $this->dgenerations = 1; } }
/** * 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; switch (Filter::get('action')) { case 'deletenews': $news_id = Filter::getInteger('news_id'); if ($news_id) { Database::prepare("DELETE FROM `##news` WHERE news_id = ?")->execute(array($news_id)); } break; } $articles = Database::prepare("SELECT SQL_CACHE news_id, user_id, gedcom_id, UNIX_TIMESTAMP(updated) + :offset AS updated, subject, body FROM `##news` WHERE user_id = :user_id ORDER BY updated DESC")->execute(array('offset' => WT_TIMESTAMP_OFFSET, 'user_id' => Auth::id()))->fetchAll(); $id = $this->getName() . $block_id; $class = $this->getName() . '_block'; $title = $this->getTitle(); $content = ''; if (empty($articles)) { $content .= '<p>' . I18N::translate('You have not created any journal items.') . '</p>'; } foreach ($articles as $article) { $content .= '<div class="journal_box">'; $content .= '<div class="news_title">' . Filter::escapeHtml($article->subject) . '</div>'; $content .= '<div class="news_date">' . FunctionsDate::formatTimestamp($article->updated) . '</div>'; if ($article->body == strip_tags($article->body)) { $article->body = nl2br($article->body, false); } $content .= $article->body; $content .= '<a href="#" onclick="window.open(\'editnews.php?news_id=\'+' . $article->news_id . ', \'_blank\', indx_window_specs); return false;">' . I18N::translate('Edit') . '</a>'; $content .= ' | '; $content .= '<a href="index.php?action=deletenews&news_id=' . $article->news_id . '&ctype=' . $ctype . '&ged=' . $WT_TREE->getNameHtml() . '" onclick="return confirm(\'' . I18N::translate('Are you sure you want to delete “%s”?', Filter::escapeHtml($article->subject)) . "');\">" . I18N::translate('Delete') . '</a><br>'; $content .= '</div><br>'; } $content .= '<p><a href="#" onclick="window.open(\'editnews.php?user_id=' . Auth::id() . '\', \'_blank\', indx_window_specs); return false;">' . I18N::translate('Add a journal entry') . '</a></p>'; if ($template) { return Theme::theme()->formatBlock($id, $title, $class, $content); } else { return $content; } }
/** * Create the hourglass controller. * * @param string $rootid * @param int $show_full * @param bool $loadJS */ public function __construct($rootid = '', $show_full = 1, $loadJS = true) { global $WT_TREE; parent::__construct($show_full); // Extract parameters from $this->show_spouse = Filter::getInteger('show_spouse', 0, 1, 0); $this->generations = Filter::getInteger('generations', 2, $WT_TREE->getPreference('MAX_DESCENDANCY_GENERATIONS'), 3); $this->canLoadJS = $loadJS; //-- flip the arrows for RTL languages if (I18N::direction() === 'ltr') { $this->left_arrow = 'icon-larrow'; $this->right_arrow = 'icon-rarrow'; } else { $this->left_arrow = 'icon-rarrow'; $this->right_arrow = 'icon-larrow'; } $this->bhalfheight = (int) ($this->getBoxDimensions()->height / 2); //Checks how many generations of descendency is for the person for formatting purposes $this->dgenerations = $this->maxDescendencyGenerations($this->root, 0); if ($this->dgenerations < 1) { $this->dgenerations = 1; } $this->setPageTitle(I18N::translate('Hourglass chart of %s', $this->root->getFullName())); }
* 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; /** * Defined in session.php * * @global Tree $WT_TREE */ global $WT_TREE; use Fisharebest\Webtrees\Controller\PageController; use Fisharebest\Webtrees\Module\CkeditorModule; define('WT_SCRIPT_NAME', 'block_edit.php'); require './includes/session.php'; $block_id = Filter::getInteger('block_id'); $block = Database::prepare("SELECT SQL_CACHE * FROM `##block` WHERE block_id=?")->execute(array($block_id))->fetchOneRow(); // Check access. (1) the block must exist and be enabled, (2) gedcom blocks require // managers, (3) user blocks require the user or an admin $blocks = Module::getActiveBlocks($WT_TREE); if (!$block || !array_key_exists($block->module_name, $blocks) || $block->gedcom_id && !Auth::isManager(Tree::findById($block->gedcom_id)) || $block->user_id && $block->user_id != Auth::id() && !Auth::isAdmin()) { header('Location: ' . WT_BASE_URL); return; } $block = $blocks[$block->module_name]; if (Filter::post('save')) { $ctype = Filter::post('ctype', 'user', 'gedcom'); header('Location: ' . WT_BASE_URL . 'index.php?ctype=' . $ctype . '&ged=' . $WT_TREE->getNameUrl()); $block->configureBlock($block_id); return; }
/** * Display a map showing the originas of ones ancestors. */ private function pedigreeMap() { global $controller, $WT_TREE; $MAX_PEDIGREE_GENERATIONS = $WT_TREE->getPreference('MAX_PEDIGREE_GENERATIONS'); $controller = new ChartController(); $this->generations = Filter::getInteger('PEDIGREE_GENERATIONS', 2, $WT_TREE->getPreference('MAX_PEDIGREE_GENERATIONS'), $WT_TREE->getPreference('DEFAULT_PEDIGREE_GENERATIONS')); $this->treesize = pow(2, $this->generations) - 1; $this->ancestors = array_values($controller->sosaAncestors($this->generations)); // Start of internal configuration variables // Limit this to match available number of icons. // 8 generations equals 255 individuals $MAX_PEDIGREE_GENERATIONS = min($MAX_PEDIGREE_GENERATIONS, 8); // End of internal configuration variables $controller->setPageTitle(I18N::translate('Pedigree map of %s', $controller->root->getFullName()))->pageHeader()->addExternalJavascript(WT_AUTOCOMPLETE_JS_URL)->addInlineJavascript('autocomplete();'); echo '<link type="text/css" href="', WT_STATIC_URL, WT_MODULES_DIR, 'googlemap/css/wt_v3_googlemap.css" rel="stylesheet">'; echo '<div id="pedigreemap-page"> <h2>', $controller->getPageTitle(), '</h2>'; // -- print the form to change the number of displayed generations ?> <form name="people" method="get" action="?"> <input type="hidden" name="ged" value="<?php echo $WT_TREE->getNameHtml(); ?> "> <input type="hidden" name="mod" value="googlemap"> <input type="hidden" name="mod_action" value="pedigree_map"> <table class="list_table" width="555"> <tr> <td class="descriptionbox wrap"> <?php echo I18N::translate('Individual'); ?> </td> <td class="optionbox"> <input class="pedigree_form" data-autocomplete-type="INDI" type="text" id="rootid" name="rootid" size="3" value="<?php echo $controller->root->getXref(); ?> "> <?php echo FunctionsPrint::printFindIndividualLink('rootid'); ?> </td> <td class="topbottombar" rowspan="2"> <input type="submit" value="<?php echo I18N::translate('View'); ?> "> </td> </tr> <tr> <td class="descriptionbox wrap"> <?php echo I18N::translate('Generations'); ?> </td> <td class="optionbox"> <select name="PEDIGREE_GENERATIONS"> <?php for ($p = 3; $p <= $MAX_PEDIGREE_GENERATIONS; $p++) { echo '<option value="', $p, '" '; if ($p == $this->generations) { echo 'selected'; } echo '>', $p, '</option>'; } ?> </select> </td> </tr> </table> </form> <!-- end of form --> <!-- count records by type --> <?php $curgen = 1; $priv = 0; $count = 0; $miscount = 0; $missing = ''; $latlongval = array(); $lat = array(); $lon = array(); for ($i = 0; $i < $this->treesize; $i++) { // -- check to see if we have moved to the next generation if ($i + 1 >= pow(2, $curgen)) { $curgen++; } $person = $this->ancestors[$i]; if (!empty($person)) { $name = $person->getFullName(); if ($name == I18N::translate('Private')) { $priv++; } $place = $person->getBirthPlace(); if (empty($place)) { $latlongval[$i] = null; } else { $latlongval[$i] = $this->getLatitudeAndLongitudeFromPlaceLocation($person->getBirthPlace()); } if ($latlongval[$i]) { $lat[$i] = str_replace(array('N', 'S', ','), array('', '-', '.'), $latlongval[$i]->pl_lati); $lon[$i] = str_replace(array('E', 'W', ','), array('', '-', '.'), $latlongval[$i]->pl_long); if ($lat[$i] && $lon[$i]) { $count++; } else { // The place is in the table but has empty values if ($name) { if ($missing) { $missing .= ', '; } $missing .= '<a href="' . $person->getHtmlUrl() . '">' . $name . '</a>'; $miscount++; } } } else { // There was no place, or not listed in the map table if ($name) { if ($missing) { $missing .= ', '; } $missing .= '<a href="' . $person->getHtmlUrl() . '">' . $name . '</a>'; $miscount++; } } } } //<!-- end of count records by type --> //<!-- start of map display --> echo '<div id="pedigreemap_chart">'; echo '<table class="tabs_table" cellspacing="0" cellpadding="0" border="0" width="100%">'; echo '<tr>'; echo '<td valign="top">'; echo '<div id="pm_map" style="border: 1px solid gray; height: ', $this->getSetting('GM_YSIZE'), 'px; font-size: 0.9em;'; echo '"><i class="icon-loading-large"></i></div>'; if (Auth::isAdmin()) { echo '<table width="100%">'; echo '<tr><td align="left">'; echo '<a href="module.php?mod=googlemap&mod_action=admin_config">', I18N::translate('Google Maps™ preferences'), '</a>'; echo '</td>'; echo '<td align="center">'; echo '<a href="module.php?mod=googlemap&mod_action=admin_places">', I18N::translate('Geographic data'), '</a>'; echo '</td>'; echo '<td align="right">'; echo '<a href="module.php?mod=googlemap&mod_action=admin_placecheck">', I18N::translate('Place check'), '</a>'; echo '</td></tr>'; echo '</table>'; } echo '</td><td width="15px"></td>'; echo '<td width="310px" valign="top">'; echo '<div id="side_bar" style="width:300px; font-size:0.9em; overflow:auto; overflow-x:hidden; overflow-y:auto; height:', $this->getSetting('GM_YSIZE'), 'px;"></div></td>'; echo '</tr>'; echo '</table>'; // display info under map echo '<hr>'; echo '<table cellspacing="0" cellpadding="0" border="0" width="100%">'; echo '<tr>'; echo '<td valign="top">'; // print summary statistics if (isset($curgen)) { $total = pow(2, $curgen) - 1; echo I18N::plural('%1$s individual displayed, out of the normal total of %2$s, from %3$s generations.', '%1$s individuals displayed, out of the normal total of %2$s, from %3$s generations.', $count, I18N::number($count), I18N::number($total), I18N::number($curgen)), '<br>'; echo '</td>'; echo '</tr>'; echo '<tr>'; echo '<td valign="top">'; if ($priv) { echo I18N::plural('%s individual is private.', '%s individuals are private.', $priv, $priv), '<br>'; } if ($count + $priv != $total) { if ($miscount == 0) { echo I18N::translate('No ancestors in the database.'), "<br>"; } else { echo I18N::plural('%1$s individual is missing birthplace map coordinates: %2$s.', '%1$s individuals are missing birthplace map coordinates: %2$s.', $miscount, I18N::number($miscount), $missing), '<br>'; } } } echo '</td>'; echo '</tr>'; echo '</table>'; echo '</div>'; // close #pedigreemap_chart echo '</div>'; // close #pedigreemap-page ?> <!-- end of map display --> <!-- Start of map scripts --> <?php echo '<script src="', $this->googleMapsScript(), '"></script>'; $controller->addInlineJavascript($this->pedigreeMapJavascript()); }
// This becomes a JSON list, not array, so need to fetch with numeric keys. $data = Database::prepare($sql_select . $where . $order_by . $limit)->execute($args)->fetchAll(PDO::FETCH_NUM); foreach ($data as &$datum) { $datum[2] = I18N::translate($datum[2]); $datum[3] = '<a href="gedrecord.php?pid=' . $datum[3] . '&ged=' . $datum[7] . '">' . $datum[3] . '</a>'; $datum[4] = '<div class="gedcom-data" dir="ltr">' . Filter::escapeHtml($datum[4]) . '</div>'; $datum[5] = '<div class="gedcom-data" dir="ltr">' . Filter::escapeHtml($datum[5]) . '</div>'; $datum[6] = Filter::escapeHtml($datum[6]); $datum[7] = Filter::escapeHtml($datum[7]); } // 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 */ { },
/** * Startup activity */ public function __construct() { global $WT_TREE; parent::__construct(); $this->setPageTitle(I18N::translate('Timeline')); $this->baseyear = (int) date('Y'); $pids = Filter::getArray('pids', WT_REGEX_XREF); $remove = Filter::get('remove', WT_REGEX_XREF); foreach (array_unique($pids) as $pid) { if ($pid !== $remove) { $person = Individual::getInstance($pid, $WT_TREE); if ($person && $person->canShow()) { $this->people[] = $person; } } } $this->pidlinks = ''; foreach ($this->people as $indi) { // setup string of valid pids for links $this->pidlinks .= 'pids%5B%5D=' . $indi->getXref() . '&'; $bdate = $indi->getBirthDate(); if ($bdate->isOK()) { $date = new GregorianDate($bdate->minimumJulianDay()); $this->birthyears[$indi->getXref()] = $date->y; $this->birthmonths[$indi->getXref()] = max(1, $date->m); $this->birthdays[$indi->getXref()] = max(1, $date->d); } // find all the fact information $facts = $indi->getFacts(); foreach ($indi->getSpouseFamilies() as $family) { foreach ($family->getFacts() as $fact) { $facts[] = $fact; } } foreach ($facts as $event) { // get the fact type $fact = $event->getTag(); if (!in_array($fact, $this->nonfacts)) { // check for a date $date = $event->getDate(); if ($date->isOK()) { $date = new GregorianDate($date->minimumJulianDay()); $this->baseyear = min($this->baseyear, $date->y); $this->topyear = max($this->topyear, $date->y); if (!$indi->isDead()) { $this->topyear = max($this->topyear, (int) date('Y')); } // do not add the same fact twice (prevents marriages from being added multiple times) if (!in_array($event, $this->indifacts, true)) { $this->indifacts[] = $event; } } } } } $scale = Filter::getInteger('scale', 0, 200); if ($scale === 0) { $this->scale = (int) (($this->topyear - $this->baseyear) / 20 * count($this->indifacts) / 4); if ($this->scale < 6) { $this->scale = 6; } } else { $this->scale = $scale; } if ($this->scale < 2) { $this->scale = 2; } $this->baseyear -= 5; $this->topyear += 5; }
/** * Defined in session.php * * @global Tree $WT_TREE */ global $WT_TREE; use Fisharebest\Webtrees\Controller\RelationshipController; use Fisharebest\Webtrees\Functions\Functions; use Fisharebest\Webtrees\Functions\FunctionsEdit; use Fisharebest\Webtrees\Functions\FunctionsPrint; define('WT_SCRIPT_NAME', 'relationship.php'); require './includes/session.php'; $controller = new RelationshipController(); $pid1 = Filter::get('pid1', WT_REGEX_XREF); $pid2 = Filter::get('pid2', WT_REGEX_XREF); $show_full = Filter::getInteger('show_full', 0, 1, $WT_TREE->getPreference('PEDIGREE_FULL_DETAILS')); $find_all = Filter::getBool('find_all'); $person1 = Individual::getInstance($pid1, $WT_TREE); $person2 = Individual::getInstance($pid2, $WT_TREE); $controller->addExternalJavascript(WT_AUTOCOMPLETE_JS_URL)->addInlineJavascript('autocomplete();'); if ($person1 && $person2) { $controller->setPageTitle(I18N::translate('Relationships between %1$s and %2$s', $person1->getFullName(), $person2->getFullName()))->pageHeader(); $paths = $controller->calculateRelationships($person1, $person2, $find_all); } else { $controller->setPageTitle(I18N::translate('Relationships'))->pageHeader(); $paths = array(); } ?> <h2><?php echo $controller->getPageTitle(); ?>
</a></li> <li class="active"><?php echo $controller->getPageTitle(); ?> </li> </ol> <h1><?php echo $controller->getPageTitle(); ?> </h1> <form method="post" action="?action=cleanup2"> <table class="table table-bordered"> <?php // Check for idle users $month = Filter::getInteger('month', 1, 12, 6); echo '<tr><th colspan="2">', I18N::translate('Number of months since the last sign-in for a user’s account to be considered inactive: '), '</th>'; echo '<td><select onchange="document.location=options[selectedIndex].value;">'; for ($i = 1; $i <= 12; $i++) { echo '<option value="admin_users.php?action=cleanup&month=' . $i . '" '; if ($i === $month) { echo 'selected'; } echo '>', $i, '</option>'; } echo '</select></td></tr>'; // Check users not logged in too long $ucnt = 0; foreach (User::all() as $user) { if ($user->getPreference('sessiontime') === '0') { $datelogin = (int) $user->getPreference('reg_timestamp');
/** * Create any of the other blocks. * * Use as #callBlock:block_name# * * @param string[] $params * * @return string */ public function callBlock($params = array()) { global $ctype; if (isset($params[0]) && $params[0] != '') { $block = $params[0]; } else { return ''; } $all_blocks = array(); foreach (Module::getActiveBlocks($this->tree) as $name => $active_block) { if ($ctype == 'user' && $active_block->isUserBlock() || $ctype == 'gedcom' && $active_block->isGedcomBlock()) { $all_blocks[$name] = $active_block; } } if (!array_key_exists($block, $all_blocks) || $block == 'html') { return ''; } // Build the config array array_shift($params); $cfg = array(); foreach ($params as $config) { $bits = explode('=', $config); if (count($bits) < 2) { continue; } $v = array_shift($bits); $cfg[$v] = implode('=', $bits); } $block = $all_blocks[$block]; $block_id = Filter::getInteger('block_id'); $content = $block->getBlock($block_id, false, $cfg); return $content; }
/** * Display a map showing the origins of ones ancestors. */ private function pedigreeMap() { global $controller, $WT_TREE; $MAX_PEDIGREE_GENERATIONS = $WT_TREE->getPreference('MAX_PEDIGREE_GENERATIONS'); // Limit this to match available number of icons. // 8 generations equals 255 individuals $MAX_PEDIGREE_GENERATIONS = min($MAX_PEDIGREE_GENERATIONS, 8); $controller = new ChartController(); $generations = Filter::getInteger('PEDIGREE_GENERATIONS', 2, $MAX_PEDIGREE_GENERATIONS, $WT_TREE->getPreference('DEFAULT_PEDIGREE_GENERATIONS')); $this->treesize = pow(2, $generations) - 1; $this->ancestors = array_values($controller->sosaAncestors($generations)); $controller->setPageTitle(I18N::translate('Pedigree map of %s', $controller->root->getFullName()))->pageHeader()->addExternalJavascript(WT_AUTOCOMPLETE_JS_URL)->addInlineJavascript("\n\t\t\t\tjQuery('head').prepend('<link type=\"text/css\" href =\"" . WT_STATIC_URL . WT_MODULES_DIR . "googlemap/css/wt_v3_googlemap.css\" rel=\"stylesheet\">');\n\t\t\t\tautocomplete();" . $this->pedigreeMapJavascript()); echo '<div id="pedigreemap-page"><h2>', $controller->getPageTitle(), '</h2>'; // -- print the form to change the number of displayed generations ?> <form name="people" method="get" action="?"> <input type="hidden" name="ged" value="<?php echo $WT_TREE->getNameHtml(); ?> "> <input type="hidden" name="mod" value="googlemap"> <input type="hidden" name="mod_action" value="pedigree_map"> <table class="list_table"> <tr> <td class="descriptionbox wrap"> <label for="rootid"> <?php echo I18N::translate('Individual'); ?> </label> </td> <td class="optionbox"> <input class="pedigree_form" data-autocomplete-type="INDI" type="text" id="rootid" name="rootid" size="3" value="<?php echo $controller->root->getXref(); ?> "> <?php echo FunctionsPrint::printFindIndividualLink('rootid'); ?> </td> <td class="topbottombar" rowspan="2"> <input type="submit" value="<?php echo I18N::translate('view'); ?> "> </td> </tr> <tr> <td class="descriptionbox wrap"> <label for="PEDIGREE_GENERATIONS"> <?php echo I18N::translate('Generations'); ?> </label> </td> <td class="optionbox"> <select name="PEDIGREE_GENERATIONS" id="PEDIGREE_GENERATIONS"> <?php for ($p = 3; $p <= $MAX_PEDIGREE_GENERATIONS; $p++) { echo '<option value="', $p, '" '; if ($p == $generations) { echo 'selected'; } echo '>', $p, '</option>'; } ?> </select> </td> </tr> </table> </form> <!-- end of form --> <!-- count records by type --> <?php $curgen = 1; $priv = 0; $count = 0; $miscount = 0; $missing = array(); $latlongval = array(); $lat = array(); $lon = array(); for ($i = 0; $i < $this->treesize; $i++) { // -- check to see if we have moved to the next generation if ($i + 1 >= pow(2, $curgen)) { $curgen++; } $person = $this->ancestors[$i]; if (!empty($person)) { $name = $person->getFullName(); if ($name == I18N::translate('Private')) { $priv++; } $place = $person->getBirthPlace(); if (empty($place)) { $latlongval[$i] = null; } else { $latlongval[$i] = $this->getLatitudeAndLongitudeFromPlaceLocation($person->getBirthPlace()); } if ($latlongval[$i]) { $lat[$i] = strtr($latlongval[$i]->pl_lati, array('N' => '', 'S' => '-', ',' => '.')); $lon[$i] = strtr($latlongval[$i]->pl_long, array('N' => '', 'S' => '-', ',' => '.')); if ($lat[$i] && $lon[$i]) { $count++; } else { // The place is in the table but has empty values if ($name) { $missing[] = '<a href="' . $person->getHtmlUrl() . '">' . $name . '</a>'; $miscount++; } } } else { // There was no place, or not listed in the map table if ($name) { $missing[] = '<a href="' . $person->getHtmlUrl() . '">' . $name . '</a>'; $miscount++; } } } } //<!-- end of count records by type --> //<!-- start of map display --> echo '<div class="gm-pedigree-map">'; echo '<div class="gm-wrapper">'; echo '<div class="gm-map"><i class="icon-loading-large"></i></div>'; echo '<div class="gm-ancestors"></div>'; echo '</div>'; if (Auth::isAdmin()) { echo '<div class="gm-options noprint">'; echo '<a href="module.php?mod=' . $this->getName() . '&mod_action=admin_config">' . I18N::translate('Google Maps™ preferences') . '</a>'; echo ' | <a href="module.php?mod=' . $this->getName() . '&mod_action=admin_places">' . I18N::translate('Geographic data') . '</a>'; echo ' | <a href="module.php?mod=' . $this->getName() . '&mod_action=admin_placecheck">' . I18N::translate('Place check') . '</a>'; echo '</div>'; } // display info under map echo '<hr>'; // print summary statistics if (isset($curgen)) { $total = pow(2, $curgen) - 1; echo '<div>'; echo I18N::plural('%1$s individual displayed, out of the normal total of %2$s, from %3$s generations.', '%1$s individuals displayed, out of the normal total of %2$s, from %3$s generations.', $count, I18N::number($count), I18N::number($total), I18N::number($curgen)); echo '</div>'; if ($priv) { echo '<div>' . I18N::plural('%s individual is private.', '%s individuals are private.', $priv, $priv), '</div>'; } if ($count + $priv != $total) { if ($miscount == 0) { echo '<div>' . I18N::translate('No ancestors in the database.'), '</div>'; } else { echo '<div>' . I18N::plural('%1$s individual is missing birthplace map coordinates: %2$s.', '%1$s individuals are missing birthplace map coordinates: %2$s.', $miscount, I18N::number($miscount), implode(I18N::$list_separator, $missing)), '</div>'; } } } echo '</div>'; echo '</div>'; echo '<script src="', $this->googleMapsScript(), '"></script>'; }
/** * Respond to a request to delete a story. */ private function delete() { global $WT_TREE; if (Auth::isEditor($WT_TREE)) { $block_id = Filter::getInteger('block_id'); Database::prepare("DELETE FROM `##block_setting` WHERE block_id=?")->execute(array($block_id)); Database::prepare("DELETE FROM `##block` WHERE block_id=?")->execute(array($block_id)); } else { header('Location: ' . WT_BASE_URL); exit; } }
define('WT_SCRIPT_NAME', 'medialist.php'); require './includes/session.php'; $controller = new PageController(); $controller->setPageTitle(I18N::translate('Media objects'))->pageHeader(); $action = Filter::get('action'); $sortby = Filter::get('sortby', 'file|title', 'title'); if (!Auth::isEditor($WT_TREE)) { $sortby = 'title'; } $page = Filter::getInteger('page'); $max = Filter::get('max', '10|20|30|40|50|75|100|125|150|200', '20'); $folder = Filter::get('folder', null, ''); // MySQL needs an empty string, not NULL $filter = Filter::get('filter', null, ''); // MySQL needs an empty string, not NULL $columns = Filter::getInteger('columns', 1, 2, 2); $subdirs = Filter::get('subdirs', 'on'); $form_type = Filter::get('form_type', implode('|', array_keys(GedcomTag::getFileFormTypes()))); $currentdironly = $subdirs === 'on' ? false : true; // reset all variables if ($action === 'reset') { $sortby = 'title'; $max = '20'; $folder = ''; $columns = '2'; $currentdironly = true; $filter = ''; $form_type = ''; } // A list of all subfolders used by this tree $folders = QueryMedia::folderList();
$i++; } $zmax = $i; $zmax1 = $zmax - 1; $date = new Date('AFT ' . $hulpar[$zmax1]); $legend[$zmax] = strip_tags($date->display()); $z_boundaries[$zmax] = 10000; $zmax = $zmax + 1; if ($zmax > 8) { $zmax = 8; } } global $legend, $xdata, $ydata, $xmax, $zmax, $z_boundaries, $xgiven, $zgiven, $percentage, $male_female; $x_axis = Filter::getInteger('x-as', 1, 21, 11); $y_axis = Filter::getInteger('y-as', 201, 202, 201); $z_axis = Filter::getInteger('z-as', 300, 302, 302); $stats = new Stats($WT_TREE); $z_boundaries = array(); echo '<div class="statistics_chart" title="', I18N::translate('Statistics plot'), '">'; switch ($x_axis) { case '1': echo $stats->chartDistribution(array(Filter::get('chart_shows'), Filter::get('chart_type'), Filter::get('SURN'))); break; case '2': echo $stats->chartDistribution(array(Filter::get('chart_shows'), 'birth_distribution_chart')); break; case '3': echo $stats->chartDistribution(array(Filter::get('chart_shows'), 'death_distribution_chart')); break; case '4': echo $stats->chartDistribution(array(Filter::get('chart_shows'), 'marriage_distribution_chart'));
/** * Respond to a request to move a FAQ up the list. */ private function moveup() { $block_id = Filter::getInteger('block_id'); $block_order = Database::prepare("SELECT block_order FROM `##block` WHERE block_id = :block_id")->execute(array('block_id' => $block_id))->fetchOne(); $swap_block = Database::prepare("SELECT block_order, block_id" . " FROM `##block`" . " WHERE block_order = (" . " SELECT MAX(block_order) FROM `##block` WHERE block_order < :block_order AND module_name = :module_name_1" . " ) AND module_name = :module_name_2" . " LIMIT 1")->execute(array('block_order' => $block_order, 'module_name_1' => $this->getName(), 'module_name_2' => $this->getName()))->fetchOneRow(); if ($swap_block) { Database::prepare("UPDATE `##block` SET block_order = :block_order WHERE block_id = :block_id")->execute(array('block_order' => $swap_block->block_order, 'block_id' => $block_id)); Database::prepare("UPDATE `##block` SET block_order = :block_order WHERE block_id = :block_id")->execute(array('block_order' => $block_order, 'block_id' => $swap_block->block_id)); } }
/** * Defined in session.php * * @global Tree $WT_TREE */ global $WT_TREE; use Fisharebest\Webtrees\Controller\SimpleController; use Fisharebest\Webtrees\Functions\FunctionsImport; define('WT_SCRIPT_NAME', 'edit_changes.php'); require './includes/session.php'; $controller = new SimpleController(); $controller->restrictAccess(Auth::isModerator($WT_TREE))->setPageTitle(I18N::translate('Pending changes'))->pageHeader()->addInlineJavascript("\n\t\tfunction show_diff(diffurl) {\n\t\t\twindow.opener.location = diffurl;\n\t\t\treturn false;\n\t\t}\n\t"); $action = Filter::get('action'); $change_id = Filter::getInteger('change_id'); $index = Filter::get('index'); $ged = Filter::getInteger('ged'); echo '<div id="pending"><h2>', I18N::translate('Pending changes'), '</h2>'; switch ($action) { case 'undo': $gedcom_id = Database::prepare("SELECT gedcom_id FROM `##change` WHERE change_id=?")->execute(array($change_id))->fetchOne(); $xref = Database::prepare("SELECT xref FROM `##change` WHERE change_id=?")->execute(array($change_id))->fetchOne(); // Undo a change, and subsequent changes to the same record Database::prepare("UPDATE `##change`" . " SET status = 'rejected'" . " WHERE status = 'pending'" . " AND gedcom_id = ?" . " AND xref = ?" . " AND change_id >= ?")->execute(array($gedcom_id, $xref, $change_id)); break; case 'accept': $gedcom_id = Database::prepare("SELECT gedcom_id FROM `##change` WHERE change_id=?")->execute(array($change_id))->fetchOne(); $xref = Database::prepare("SELECT xref FROM `##change` WHERE change_id=?")->execute(array($change_id))->fetchOne(); // Accept a change, and all previous changes to the same record $changes = Database::prepare("SELECT change_id, gedcom_id, gedcom_name, xref, old_gedcom, new_gedcom" . " FROM `##change` c" . " JOIN `##gedcom` g USING (gedcom_id)" . " WHERE c.status = 'pending'" . " AND gedcom_id = ?" . " AND xref = ?" . " AND change_id <= ?" . " ORDER BY change_id")->execute(array($gedcom_id, $xref, $change_id))->fetchAll(); foreach ($changes as $change) { if (empty($change->new_gedcom)) {
/** {@inheritdoc} */ public function modAction($mod_action) { Database::updateSchema(self::SCHEMA_MIGRATION_PREFIX, self::SCHEMA_SETTING_NAME, self::SCHEMA_TARGET_VERSION); switch ($mod_action) { case 'admin_config': $template = new AdminTemplate(); return $template->pageContent(); case 'admin_search': // new settings $surname = Filter::post('SURNAME'); $pid = Filter::post('PID'); if ($surname) { $soundex_std = Filter::postBool('soundex_std'); $soundex_dm = Filter::postBool('soundex_dm'); $indis = $this->module()->indisArray($surname, $soundex_std, $soundex_dm); usort($indis, 'Fisharebest\\Webtrees\\Individual::compareBirthDate'); if (isset($indis) && count($indis) > 0) { $pid = $indis[0]->getXref(); } else { $result['error'] = I18N::translate('Error: The surname you entered doesn’t exist in this tree.'); } } if (isset($pid)) { $FTV_SETTINGS = unserialize($this->getSetting('FTV_SETTINGS')); if ($this->module()->searchArray($this->module()->searchArray($FTV_SETTINGS, 'TREE', Filter::getInteger('tree')), 'PID', $pid)) { if ($surname) { $result['error'] = I18N::translate('Error: The root person belonging to this surname already exists'); } else { $result['error'] = I18N::translate('Error: A root person with ID %s already exists', $pid); } } else { $record = Individual::getInstance($pid, $this->tree); if ($record) { $root = $record->getFullName() . ' (' . $record->getLifeSpan() . ')'; $title = $this->module()->getPageLink($pid); $result = array('access_level' => '2', 'pid' => $pid, 'root' => $root, 'sort' => count($this->module()->searchArray($FTV_SETTINGS, 'TREE', Filter::getInteger('tree'))) + 1, 'surname' => $this->module()->getSurname($pid), 'title' => $title, 'tree' => Filter::getInteger('tree')); } else { if (empty($result['error'])) { $result['error'] = I18N::translate('Error: A person with ID %s does not exist in this tree', $pid); } } } } echo json_encode($result); break; case 'admin_add': $FTV_SETTINGS = unserialize($this->getSetting('FTV_SETTINGS')); $NEW_FTV_SETTINGS = $FTV_SETTINGS; $NEW_FTV_SETTINGS[] = array('TREE' => Filter::getInteger('tree'), 'SURNAME' => Filter::post('surname'), 'PID' => Filter::post('pid'), 'ACCESS_LEVEL' => Filter::postInteger('access_level'), 'SORT' => Filter::postInteger('sort')); $this->setSetting('FTV_SETTINGS', serialize(array_values($NEW_FTV_SETTINGS))); Log::addConfigurationLog($this->getTitle() . ' config updated'); break; case 'admin_update': $FTV_SETTINGS = unserialize($this->getSetting('FTV_SETTINGS')); $new_surname = Filter::postArray('surname'); $new_access_level = Filter::postArray('access_level'); $new_sort = Filter::postArray('sort'); foreach ($new_surname as $key => $new_surname) { $FTV_SETTINGS[$key]['SURNAME'] = $new_surname; } foreach ($new_access_level as $key => $new_access_level) { $FTV_SETTINGS[$key]['ACCESS_LEVEL'] = $new_access_level; } foreach ($new_sort as $key => $new_sort) { $FTV_SETTINGS[$key]['SORT'] = $new_sort; } $NEW_FTV_SETTINGS = $this->module()->sortArray($FTV_SETTINGS, 'SORT'); $this->setSetting('FTV_SETTINGS', serialize($NEW_FTV_SETTINGS)); break; case 'admin_save': $FTV_OPTIONS = unserialize($this->getSetting('FTV_OPTIONS')); $FTV_OPTIONS[Filter::getInteger('tree')] = Filter::postArray('NEW_FTV_OPTIONS'); $this->setSetting('FTV_OPTIONS', serialize($FTV_OPTIONS)); Log::addConfigurationLog($this->getTitle() . ' config updated'); // the cache has to be recreated because the image options could have been changed $this->module()->emptyCache(); break; case 'admin_reset': $FTV_OPTIONS = unserialize($this->getSetting('FTV_OPTIONS')); unset($FTV_OPTIONS[Filter::getInteger('tree')]); $this->setSetting('FTV_OPTIONS', serialize($FTV_OPTIONS)); Log::addConfigurationLog($this->getTitle() . ' options set to default'); break; case 'admin_delete': $FTV_SETTINGS = unserialize($this->getSetting('FTV_SETTINGS')); unset($FTV_SETTINGS[Filter::getInteger('key')]); $this->setSetting('FTV_SETTINGS', serialize($FTV_SETTINGS)); Log::addConfigurationLog($this->getTitle() . ' item deleted'); break; case 'page': $template = new PageTemplate(); return $template->pageContent(); // See mediafirewall.php // See mediafirewall.php case 'thumbnail': $mid = Filter::get('mid', WT_REGEX_XREF); $media = Media::getInstance($mid, $this->tree); $mimetype = $media->mimeType(); $cache_filename = $this->module()->cacheFileName($media); $filetime = filemtime($cache_filename); $filetimeHeader = gmdate('D, d M Y H:i:s', $filetime) . ' GMT'; $expireOffset = 3600 * 24 * 7; // tell browser to cache this image for 7 days $expireHeader = gmdate('D, d M Y H:i:s', WT_TIMESTAMP + $expireOffset) . ' GMT'; $etag = $media->getEtag(); $filesize = filesize($cache_filename); // parse IF_MODIFIED_SINCE header from client $if_modified_since = 'x'; if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) { $if_modified_since = preg_replace('/;.*$/', '', $_SERVER['HTTP_IF_MODIFIED_SINCE']); } // parse IF_NONE_MATCH header from client $if_none_match = 'x'; if (isset($_SERVER['HTTP_IF_NONE_MATCH'])) { $if_none_match = str_replace('"', '', $_SERVER['HTTP_IF_NONE_MATCH']); } // add caching headers. allow browser to cache file, but not proxy header('Last-Modified: ' . $filetimeHeader); header('ETag: "' . $etag . '"'); header('Expires: ' . $expireHeader); header('Cache-Control: max-age=' . $expireOffset . ', s-maxage=0, proxy-revalidate'); // if this file is already in the user’s cache, don’t resend it // first check if the if_modified_since param matches if ($if_modified_since === $filetimeHeader) { // then check if the etag matches if ($if_none_match === $etag) { http_response_code(304); return; } } // send headers for the image header('Content-Type: ' . $mimetype); header('Content-Disposition: filename="' . basename($cache_filename) . '"'); header('Content-Length: ' . $filesize); // Some servers disable fpassthru() and readfile() if (function_exists('readfile')) { readfile($cache_filename); } else { $fp = fopen($cache_filename, 'rb'); if (function_exists('fpassthru')) { fpassthru($fp); } else { while (!feof($fp)) { echo fread($fp, 65536); } } fclose($fp); } break; case 'show_pdf': $template = new PdfTemplate(); return $template->pageBody(); case 'pdf_data': $template = new PdfTemplate(); return $template->pageData(); case 'pdf_thumb_data': $xref = Filter::get('mid'); $mediaobject = Media::getInstance($xref, $this->tree); $thumb = Filter::get('thumb'); if ($thumb === '2') { // Fancy thumb echo $this->module()->cacheFileName($mediaobject); } else { echo $mediaobject->getServerFilename('thumb'); } break; default: http_response_code(404); break; } }
* but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 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?
<li><a href="admin_trees_manage.php"><?php echo I18N::translate('Manage family trees'); ?> </a></li> <li class="active"><?php echo $controller->getPageTitle(); ?> </li> </ol> <h1><?php echo $controller->getPageTitle(); ?> </h1> <?php $tree = Tree::findById(Filter::getInteger('gedcom_id')); // Check it exists if (!$tree) { break; } $gedcom_filename = $tree->getPreference('gedcom_filename'); ?> <p> <?php echo I18N::translate('This will delete all the genealogy data from “%s” and replace it with data from a GEDCOM file.', $tree->getTitleHtml()); ?> </p> <form class="form form-horizontal" name="gedcomimportform" method="post" enctype="multipart/form-data" onsubmit="return checkGedcomImportForm('<?php echo Filter::escapeHtml(I18N::translate('You have selected a GEDCOM file with a different name. Is this correct?')); ?> ');">
/** * 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(); }
/** * 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, $controller, $WT_TREE; $action = Filter::get('action'); switch ($action) { case 'deletefav': $favorite_id = Filter::getInteger('favorite_id'); if ($favorite_id) { self::deleteFavorite($favorite_id); } break; case 'addfav': $gid = Filter::get('gid', WT_REGEX_XREF); $favnote = Filter::get('favnote'); $url = Filter::getUrl('url'); $favtitle = Filter::get('favtitle'); if ($gid) { $record = GedcomRecord::getInstance($gid, $WT_TREE); if ($record && $record->canShow()) { self::addFavorite(array('user_id' => $ctype === 'user' ? Auth::id() : null, 'gedcom_id' => $WT_TREE->getTreeId(), 'gid' => $record->getXref(), 'type' => $record::RECORD_TYPE, 'url' => null, 'note' => $favnote, 'title' => $favtitle)); } } elseif ($url) { self::addFavorite(array('user_id' => $ctype === 'user' ? Auth::id() : null, 'gedcom_id' => $WT_TREE->getTreeId(), 'gid' => null, 'type' => 'URL', 'url' => $url, 'note' => $favnote, 'title' => $favtitle ? $favtitle : $url)); } break; } $block = $this->getBlockSetting($block_id, 'block', '0'); foreach (array('block') as $name) { if (array_key_exists($name, $cfg)) { ${$name} = $cfg[$name]; } } $userfavs = $this->getFavorites($ctype === 'user' ? Auth::id() : $WT_TREE->getTreeId()); if (!is_array($userfavs)) { $userfavs = array(); } $id = $this->getName() . $block_id; $class = $this->getName() . '_block'; $title = $this->getTitle(); if (Auth::check()) { $controller->addExternalJavascript(WT_AUTOCOMPLETE_JS_URL)->addInlineJavascript('autocomplete();'); } $content = ''; if ($userfavs) { foreach ($userfavs as $key => $favorite) { if (isset($favorite['id'])) { $key = $favorite['id']; } $removeFavourite = '<a class="font9" href="index.php?ctype=' . $ctype . '&ged=' . $WT_TREE->getNameHtml() . '&action=deletefav&favorite_id=' . $key . '" onclick="return confirm(\'' . I18N::translate('Are you sure you want to remove this item from your list of favorites?') . '\');">' . I18N::translate('Remove') . '</a> '; if ($favorite['type'] == 'URL') { $content .= '<div id="boxurl' . $key . '.0" class="person_box">'; if ($ctype == 'user' || Auth::isManager($WT_TREE)) { $content .= $removeFavourite; } $content .= '<a href="' . $favorite['url'] . '"><b>' . $favorite['title'] . '</b></a>'; $content .= '<br>' . $favorite['note']; $content .= '</div>'; } else { $record = GedcomRecord::getInstance($favorite['gid'], $WT_TREE); if ($record && $record->canShow()) { if ($record instanceof Individual) { $content .= '<div id="box' . $favorite["gid"] . '.0" class="person_box action_header'; switch ($record->getsex()) { case 'M': break; case 'F': $content .= 'F'; break; default: $content .= 'NN'; break; } $content .= '">'; if ($ctype == "user" || Auth::isManager($WT_TREE)) { $content .= $removeFavourite; } $content .= Theme::theme()->individualBoxLarge($record); $content .= $favorite['note']; $content .= '</div>'; } else { $content .= '<div id="box' . $favorite['gid'] . '.0" class="person_box">'; if ($ctype == 'user' || Auth::isManager($WT_TREE)) { $content .= $removeFavourite; } $content .= $record->formatList('span'); $content .= '<br>' . $favorite['note']; $content .= '</div>'; } } } } } if ($ctype == 'user' || Auth::isManager($WT_TREE)) { $uniqueID = Uuid::uuid4(); // This block can theoretically appear multiple times, so use a unique ID. $content .= '<div class="add_fav_head">'; $content .= '<a href="#" onclick="return expand_layer(\'add_fav' . $uniqueID . '\');">' . I18N::translate('Add a new favorite') . '<i id="add_fav' . $uniqueID . '_img" class="icon-plus"></i></a>'; $content .= '</div>'; $content .= '<div id="add_fav' . $uniqueID . '" style="display: none;">'; $content .= '<form name="addfavform" method="get" action="index.php">'; $content .= '<input type="hidden" name="action" value="addfav">'; $content .= '<input type="hidden" name="ctype" value="' . $ctype . '">'; $content .= '<input type="hidden" name="ged" value="' . $WT_TREE->getNameHtml() . '">'; $content .= '<div class="add_fav_ref">'; $content .= '<input type="radio" name="fav_category" value="record" checked onclick="jQuery(\'#gid' . $uniqueID . '\').removeAttr(\'disabled\'); jQuery(\'#url, #favtitle\').attr(\'disabled\',\'disabled\').val(\'\');">'; $content .= '<label for="gid' . $uniqueID . '">' . I18N::translate('Enter an individual, family, or source ID') . '</label>'; $content .= '<input class="pedigree_form" data-autocomplete-type="IFSRO" type="text" name="gid" id="gid' . $uniqueID . '" size="5" value="">'; $content .= ' ' . FunctionsPrint::printFindIndividualLink('gid' . $uniqueID); $content .= ' ' . FunctionsPrint::printFindFamilyLink('gid' . $uniqueID); $content .= ' ' . FunctionsPrint::printFindSourceLink('gid' . $uniqueID); $content .= ' ' . FunctionsPrint::printFindRepositoryLink('gid' . $uniqueID); $content .= ' ' . FunctionsPrint::printFindNoteLink('gid' . $uniqueID); $content .= ' ' . FunctionsPrint::printFindMediaLink('gid' . $uniqueID); $content .= '</div>'; $content .= '<div class="add_fav_url">'; $content .= '<input type="radio" name="fav_category" value="url" onclick="jQuery(\'#url, #favtitle\').removeAttr(\'disabled\'); jQuery(\'#gid' . $uniqueID . '\').attr(\'disabled\',\'disabled\').val(\'\');">'; $content .= '<input type="text" name="url" id="url" size="20" value="" placeholder="' . GedcomTag::getLabel('URL') . '" disabled> '; $content .= '<input type="text" name="favtitle" id="favtitle" size="20" value="" placeholder="' . I18N::translate('Title') . '" disabled>'; $content .= '<p>' . I18N::translate('Enter an optional note about this favorite') . '</p>'; $content .= '<textarea name="favnote" rows="6" cols="50"></textarea>'; $content .= '</div>'; $content .= '<input type="submit" value="' . I18N::translate('Add') . '">'; $content .= '</form></div>'; } if ($template) { if ($block) { $class .= ' small_inner_block'; } return Theme::theme()->formatBlock($id, $title, $class, $content); } else { return $content; } }
/** {@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(); }
/** * 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 }