/** * {@inhericDoc} * @see \MyArtJaub\Webtrees\Mvc\View\AbstractView::renderContent() */ protected function renderContent() { $nb_found = $this->data->get('stats_gen_nb_found'); $nb_other = $this->data->get('stats_gen_nb_other'); $nb_unknown = $this->data->get('stats_gen_nb_unknown'); $perc_known = Functions::safeDivision($nb_found - $nb_other, $nb_found + $nb_unknown); $html = '<div id="geodispersion_summary"> <div class="maj-table center"> <div class="maj-row"> <div class="label">' . I18N::translate('Places found') . '</div> <div class="value">' . I18N::translate('%1$d (%2$s)', $nb_found - $nb_other, I18N::percentage($perc_known)) . '</div> </div>'; if ($nb_other > 0) { $perc_other = Functions::safeDivision($nb_other, $nb_found + $nb_unknown); $html .= '<div class="maj-row"> <div class="label">' . I18N::translate('Other places') . '</div> <div class="value">' . I18N::translate('%1$d (%2$s)', $nb_other, I18N::percentage($perc_other)) . '</div> </div>'; } $html .= '<div class="maj-row"> <div class="label">' . I18N::translate('Places not found') . '</div> <div class="value">' . I18N::translate('%1$d (%2$s)', $nb_unknown, I18N::percentage(1 - $perc_known)) . '</div> </div> </div> </div> <br/> <div id="geodispersion_data"> ' . $this->htmlAnalysisData() . ' </div>'; return $html; }
/** * {@inheritDoc} * @see \MyArtJaub\Webtrees\Module\GeoDispersion\Views\AbstractGeoAnalysisTabGeneralView::htmlAnalysisData() */ protected function htmlAnalysisData() { $results = $this->data->get('results'); $analysis_level = $this->data->get('analysis_level'); $nb_found = $this->data->get('stats_gen_nb_found'); $nb_other = $this->data->get('stats_gen_nb_other'); $i = 1; $previous_nb = 0; $html = '<div class="maj-table center">'; foreach ($results as $place => $nb) { $perc = Functions::safeDivision($nb, $nb_found - $nb_other); if ($nb != $previous_nb) { $j = I18N::number($i); } else { $j = ' '; } $levels = array_map('trim', explode(',', $place)); $placename = $levels[$analysis_level - 1]; if ($placename == '' && $analysis_level > 1) { $placename = I18N::translate('Unknown (%s)', $levels[$analysis_level - 2]); } $html .= '<div class="maj-row"> <div class="label"><strong>' . $j . '</strong></div> <div class="label">' . $placename . '</div> <div class="value">' . I18N::translate('%d', $nb) . '</div> <div class="value">' . I18N::percentage($perc, 1) . '</div> </div>'; $i++; $previous_nb = $nb; } $html .= '</div>'; return $html; }
/** * {@inheritDoc} * @see \MyArtJaub\Webtrees\Module\DependentInterface::validatePrerequisites() */ public function validatePrerequisites() { return Functions::isEncryptionCompatible(); }
/** * Render the Ajax response for the sortable table of Sosa individuals * @param AjaxController $controller */ protected function renderSosaListIndi(AjaxController $controller) { global $WT_TREE; $listSosa = $this->sosa_provider->getSosaListAtGeneration($this->generation); $this->view_bag->set('has_sosa', false); if (count($listSosa) > 0) { $this->view_bag->set('has_sosa', true); $table_id = 'table-sosa-indi-' . Uuid::uuid4(); $this->view_bag->set('table_id', $table_id); $controller->addExternalJavascript(WT_JQUERY_DATATABLES_JS_URL)->addInlineJavascript(' jQuery.fn.dataTableExt.oSort["unicode-asc" ]=function(a,b) {return a.replace(/<[^<]*>/, "").localeCompare(b.replace(/<[^<]*>/, ""))}; jQuery.fn.dataTableExt.oSort["unicode-desc" ]=function(a,b) {return b.replace(/<[^<]*>/, "").localeCompare(a.replace(/<[^<]*>/, ""))}; jQuery.fn.dataTableExt.oSort["num-html-asc" ]=function(a,b) {a=parseFloat(a.replace(/<[^<]*>/, "")); b=parseFloat(b.replace(/<[^<]*>/, "")); return (a<b) ? -1 : (a>b ? 1 : 0);}; jQuery.fn.dataTableExt.oSort["num-html-desc"]=function(a,b) {a=parseFloat(a.replace(/<[^<]*>/, "")); b=parseFloat(b.replace(/<[^<]*>/, "")); return (a>b) ? -1 : (a<b ? 1 : 0);}; jQuery("#' . $table_id . '").dataTable( { dom: \'<"H"<"filtersH_' . $table_id . '">T<"dt-clear">pf<"dt-clear">irl>t<"F"pl<"dt-clear"><"filtersF_' . $table_id . '">>\', ' . I18N::datatablesI18N() . ', jQueryUI: true, autoWidth: false, processing: true, retrieve: true, columns: [ /* 0-Sosa */ { type: "num", class: "center" }, /* 1-ID */ { visible: false }, /* 2-givn */ { dataSort: 4, class: "left"}, /* 3-surn */ { datasort: 5}, /* 4-GIVN,SURN */ { type: "unicode", visible: false}, /* 5-SURN,GIVN */ { type: "unicode", visible: false}, /* 6-Birth */ { dataSort : 7 , class: "center"}, /* 7-SORT_BIRT */ { visible : false}, /* 8-BIRT_PLAC */ { type: "unicode", class: "center"}, /* PERSO Modify table to include IsSourced module */ /* 9-BIRT_SOUR */ { dataSort : 10, class: "center", visible: ' . (ModuleManager::getInstance()->isOperational(Constants::MODULE_MAJ_ISSOURCED_NAME) ? 'true' : 'false') . ' }, /* 10-SORT_BIRTSC */{ visible : false}, /* 11-Death */ { dataSort : 12 , class: "center"}, /* 12-SORT_DEAT */ { visible : false}, /* 13-Age */ { dataSort : 14 , class: "center"}, /* 14-AGE */ { type: "num", visible: false}, /* 15-DEAT_PLAC */ { type: "unicode", class: "center" }, /* 16-DEAT_SOUR */ { dataSort : 17, class: "center", visible: ' . (ModuleManager::getInstance()->isOperational(Constants::MODULE_MAJ_ISSOURCED_NAME) ? 'true' : 'false') . ' }, /* 17-SORT_DEATSC */{ visible : false}, /* 18-SEX */ { visible : false}, /* 19-BIRT */ { visible : false}, /* 20-DEAT */ { visible : false}, /* 21-TREE */ { visible : false} /* END PERSO */ ], sorting: [[0,"asc"]], displayLength: 16, pagingType: "full_numbers" }); jQuery("#' . $table_id . '") /* Hide/show parents */ .on("click", ".btn-toggle-parents", function() { jQuery(this).toggleClass("ui-state-active"); jQuery(".parents", jQuery(this).closest("table").DataTable().rows().nodes()).slideToggle(); }) /* Hide/show statistics */ .on("click", ".btn-toggle-statistics", function() { jQuery(this).toggleClass("ui-state-active"); jQuery("#indi_list_table-charts_' . $table_id . '").slideToggle(); }) /* Filter buttons in table header */ .on("click", "button[data-filter-column]", function() { var btn = jQuery(this); // De-activate the other buttons in this button group btn.siblings().removeClass("ui-state-active"); // Apply (or clear) this filter var col = jQuery("#' . $table_id . '").DataTable().column(btn.data("filter-column")); if (btn.hasClass("ui-state-active")) { btn.removeClass("ui-state-active"); col.search("").draw(); } else { btn.addClass("ui-state-active"); col.search(btn.data("filter-value")).draw(); } }); jQuery("#sosa-indi-list").css("visibility", "visible"); jQuery("#btn-toggle-statistics-' . $table_id . '").click(); '); $stats = new Stats($WT_TREE); // Bad data can cause "longest life" to be huge, blowing memory limits $max_age = min($WT_TREE->getPreference('MAX_ALIVE_AGE'), $stats->LongestLifeAge()) + 1; // Inititialise chart data $deat_by_age = array(); for ($age = 0; $age <= $max_age; $age++) { $deat_by_age[$age] = ''; } $birt_by_decade = array(); $deat_by_decade = array(); for ($year = 1550; $year < 2030; $year += 10) { $birt_by_decade[$year] = ''; $deat_by_decade[$year] = ''; } $unique_indis = array(); // Don't double-count indis with multiple names. $nb_displayed = 0; Individual::load($WT_TREE, $listSosa); foreach ($listSosa as $sosa => $pid) { $person = Individual::getInstance($pid, $WT_TREE); if (!$person || !$person->canShowName()) { unset($listSosa[$sosa]); continue; } $nb_displayed++; if ($birth_dates = $person->getAllBirthDates()) { if (FunctionsPrint::isDateWithinChartsRange($birth_dates[0]) && !isset($unique_indis[$person->getXref()])) { $birt_by_decade[(int) ($birth_dates[0]->gregorianYear() / 10) * 10] .= $person->getSex(); } } else { $birth_dates[0] = new Date(''); } if ($death_dates = $person->getAllDeathDates()) { if (FunctionsPrint::isDateWithinChartsRange($death_dates[0]) && !isset($unique_indis[$person->getXref()])) { $deat_by_decade[(int) ($death_dates[0]->gregorianYear() / 10) * 10] .= $person->getSex(); } } else { $death_dates[0] = new Date(''); } $age = Date::getAge($birth_dates[0], $death_dates[0], 0); if (!isset($unique_indis[$person->getXref()]) && $age >= 0 && $age <= $max_age) { $deat_by_age[$age] .= $person->getSex(); } $listSosa[$sosa] = $person; $unique_indis[$person->getXref()] = true; } $this->view_bag->set('sosa_list', $listSosa); $this->view_bag->set('sosa_count', count($listSosa)); $this->view_bag->set('sosa_theo', pow(2, $this->generation - 1)); $this->view_bag->set('sosa_ratio', Functions::safeDivision($this->view_bag->get('sosa_count'), $this->view_bag->get('sosa_theo'))); $this->view_bag->set('sosa_hidden', $this->view_bag->get('sosa_count') - $nb_displayed); $this->view_bag->set('chart_births', FunctionsPrintLists::chartByDecade($birt_by_decade, I18N::translate('Decade of birth'))); $this->view_bag->set('chart_deaths', FunctionsPrintLists::chartByDecade($deat_by_decade, I18N::translate('Decade of death'))); $this->view_bag->set('chart_ages', FunctionsPrintLists::chartByAge($deat_by_age, I18N::translate('Age related to death year'))); } ViewFactory::make('SosaListIndi', $this, $controller, $this->view_bag)->render(); }
/** * Returns HTML code for a graph showing the dispersion of ancestors across grand-parents * @return string HTML code */ private function htmlAncestorDispersionG3() { $ancestorsDispGen2 = $this->sosa_provider->getAncestorDispersionForGen(3); $size = '700x300'; $color_motmot = 'ffd1dc'; $color_motfat = 'b998a0'; $color_fatfat = '577292'; $color_fatmot = '84beff'; $color_shared = '777777'; $total_fatfat = array_key_exists(1, $ancestorsDispGen2) ? $ancestorsDispGen2[1] : 0; $total_fatmot = array_key_exists(2, $ancestorsDispGen2) ? $ancestorsDispGen2[2] : 0; $total_motfat = array_key_exists(4, $ancestorsDispGen2) ? $ancestorsDispGen2[4] : 0; $total_motmot = array_key_exists(8, $ancestorsDispGen2) ? $ancestorsDispGen2[8] : 0; $total_sha = array_key_exists(-1, $ancestorsDispGen2) ? $ancestorsDispGen2[-1] : 0; $total = $total_fatfat + $total_fatmot + $total_motfat + $total_motmot + $total_sha; $chd = $this->arrayToExtendedEncoding(array(4095 * Functions::safeDivision($total_fatfat, $total), 4095 * Functions::safeDivision($total_fatmot, $total), 4095 * Functions::safeDivision($total_sha, $total), 4095 * Functions::safeDivision($total_motfat, $total), 4095 * Functions::safeDivision($total_motmot, $total))); $chart_title = I18N::translate('Known Sosa ancestors\' dispersion - G3'); $chl = \Fisharebest\Webtrees\Functions\Functions::getRelationshipNameFromPath('fatfat') . ' - ' . I18N::percentage(Functions::safeDivision($total_fatfat, $total), 1) . '|' . \Fisharebest\Webtrees\Functions\Functions::getRelationshipNameFromPath('fatmot') . ' - ' . I18N::percentage(Functions::safeDivision($total_fatmot, $total), 1) . '|' . I18N::translate('Shared') . ' - ' . I18N::percentage(Functions::safeDivision($total_sha, $total), 1) . '|' . \Fisharebest\Webtrees\Functions\Functions::getRelationshipNameFromPath('motfat') . ' - ' . I18N::percentage(Functions::safeDivision($total_motfat, $total), 1) . '|' . \Fisharebest\Webtrees\Functions\Functions::getRelationshipNameFromPath('motmot') . ' - ' . I18N::percentage(Functions::safeDivision($total_motmot, $total), 1); return "<img src=\"https://chart.googleapis.com/chart?cht=p&chp=1.5708&chd=e:{$chd}&chs={$size}&chco={$color_fatfat},{$color_fatmot},{$color_shared},{$color_motfat},{$color_motmot}&chf=bg,s,ffffff00&chl={$chl}\" alt=\"" . $chart_title . "\" title=\"" . $chart_title . "\" />"; }
/** * Render the image to the output. */ public function render() { if (!$this->media || !$this->media->canShow()) { Log::addMediaLog('Image Builder error: >' . I18N::translate('Missing or private media object.')); $this->renderError(); } $serverFilename = $this->media->getServerFilename(); if (!file_exists($serverFilename)) { Log::addMediaLog('Image Builder error: >' . I18N::translate('The media object does not exist.') . '< for path >' . $serverFilename . '<'); $this->renderError(); } $mimetype = $this->media->mimeType(); $imgsize = $this->media->getImageAttributes(); $filetime = $this->media->getFiletime(); $filetimeHeader = gmdate('D, d M Y H:i:s', $filetime) . ' GMT'; $expireHeader = gmdate('D, d M Y H:i:s', WT_TIMESTAMP + $this->getExpireOffset()) . ' GMT'; $type = Functions::isImageTypeSupported($imgsize['ext']); $usewatermark = false; // if this image supports watermarks and the watermark module is intalled... if ($type) { $usewatermark = $this->isShowWatermark(); } // determine whether we have enough memory to watermark this image if ($usewatermark) { if (!FunctionsMedia::hasMemoryForImage($serverFilename)) { // not enough memory to watermark this file $usewatermark = false; } } $etag = $this->media->getEtag(); // parse IF_MODIFIED_SINCE header from client $if_modified_since = 'x'; if (!empty(Filter::server('HTTP_IF_MODIFIED_SINCE'))) { $if_modified_since = preg_replace('/;.*$/', '', Filter::server('HTTP_IF_MODIFIED_SINCE')); } // parse IF_NONE_MATCH header from client $if_none_match = 'x'; if (!empty(Filter::server('HTTP_IF_NONE_MATCH'))) { $if_none_match = str_replace('"', '', Filter::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=' . $this->getExpireOffset() . ', 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="' . addslashes(basename($this->media->getFilename())) . '"'); if ($usewatermark) { // generate the watermarked image $imCreateFunc = 'imagecreatefrom' . $type; $imSendFunc = 'image' . $type; if (function_exists($imCreateFunc) && function_exists($imSendFunc)) { $im = $imCreateFunc($serverFilename); $im = $this->applyWatermark($im); // send the image $imSendFunc($im); imagedestroy($im); return; } else { // this image is defective. log it Log::addMediaLog('Image Builder error: >' . I18N::translate('This media file is broken and cannot be watermarked.') . '< in file >' . $serverFilename . '< memory used: ' . memory_get_usage()); } } // determine filesize of image (could be original or watermarked version) $filesize = filesize($serverFilename); // set content-length header, send file header('Content-Length: ' . $filesize); // Some servers disable fpassthru() and readfile() if (function_exists('readfile')) { readfile($serverFilename); } else { $fp = fopen($serverFilename, 'rb'); if (function_exists('fpassthru')) { fpassthru($fp); } else { while (!feof($fp)) { echo fread($fp, 65536); } } fclose($fp); } }
/** * {@inhericDoc} * @see \MyArtJaub\Webtrees\Module\Certificates\Model\CertificateProviderInterface::getCertificatesListBeginWith() */ public function getCertificatesListBeginWith($city, $contains, $limit = 9999) { $tabFiles = array(); $dirPath = $this->getRealCertificatesDirectory() . Functions::encodeUtf8ToFileSystem($city) . '/'; $contains = utf8_decode($contains); $nbCert = 0; if (is_dir($dirPath)) { $dir = opendir($dirPath); while (($entry = readdir($dir)) && $nbCert < $limit) { if ($entry != '.' && $entry != '..' && $entry != 'Thumbs.db' && !is_dir($dirPath . $entry . '/') && stripos($entry, $contains) !== false) { $tabFiles[] = Functions::encodeFileSystemToUtf8($entry); $nbCert++; } } } sort($tabFiles); return $tabFiles; }
/** * {@inhericDoc} * @see \MyArtJaub\Webtrees\Mvc\View\AbstractView::renderContent() */ protected function renderContent() { $cities = $this->data->get('cities'); $selected_city = $this->data->get('selected_city'); ?> <div id="maj-cert-list-page" class="center"> <h2><?php echo $this->data->get('title'); ?> </h2> <form method="get" name="selcity" action="module.php"> <input type="hidden" name="mod" value="<?php echo $this->data->get('url_module'); ?> "> <input type="hidden" name="mod_action" value="<?php echo $this->data->get('url_action'); ?> "> <input type="hidden" name="ged" value="<?php echo $this->data->get('url_ged'); ?> "> <select name="city"> <?php foreach ($cities as $city) { ?> <option value="<?php echo Functions::encryptToSafeBase64($city); ?> " <?php if (trim($city) == trim($selected_city)) { echo 'selected="selected"'; } ?> ><?php echo $city; ?> </option> <?php } ?> </select> <input type="submit" value="<?php echo I18N::translate('Show'); ?> " /> </form> <?php if ($this->data->get('has_list', false)) { ?> <div class="loading-image"> </div> <div class="certificate-list"> <table id="<?php echo $this->data->get('table_id'); ?> "> <thead> <tr> <th><?php echo I18N::translate('Date'); ?> </th> <th>datesort</th> <th><?php echo I18N::translate('Type'); ?> </th> <th>certificatesort</th> <th><?php echo I18N::translate('Certificate'); ?> </th> </tr> </thead> <tbody> <?php foreach ($this->data->get('certificate_list') as $certificate) { /** @var \MyArtJaub\Webtrees\Module\Certificates\Model\Certificate $certificate */ ?> <tr> <!-- Certificate date --> <?php if ($date = $certificate->getCertificateDate()) { ?> <td><?php echo $date->display(); ?> </td> <td><?php echo $date->julianDay(); ?> </td> <?php } else { ?> <td> </td> <td>0</td> <?php } ?> <!-- Certificate Type --> <td><?php echo Filter::escapeHtml($certificate->getCertificateType() ?: ''); ?> </td> <!-- Certificate Name --> <?php $name = $certificate->getCertificateDetails() ?: ''; $sortname = ""; $ct_names = preg_match("/([A-Z]{2,})/", $name, $match); if ($ct_names > 0) { $sortname = $match[1] . '_'; } $sortname .= $name; ?> <td><?php echo Filter::escapeHtml($sortname); ?> </td> <td> <a href="<?php echo $certificate->getHtmlUrl(); ?> "><?php echo Filter::escapeHtml($name); ?> </a> </td> </tr> <?php } ?> </tbody> </table> </div> <?php } ?> </div> <?php }
/** * {@inhericDoc} * @see \Fisharebest\Webtrees\Media::getServerFilename() */ public function getServerFilename($which = 'main') { $filename = $this->provider->getRealCertificatesDirectory() . $this->getFilename(); return Functions::encodeUtf8ToFileSystem($filename); }
/** * Returns HTML code for the GeoAnalysis general tab (can be either a map or a table). * * @param GeoAnalysis $ga Reference GeoAnalysis * @param array $placesGeneralResults Analysis results at a general level * @param (null|array) $flags Array of flags * @return string HTML code for the general tab */ protected function htmlPlacesAnalysisGeneralTab(GeoAnalysis $ga, $placesGeneralResults, $flags = null) { global $WT_TREE; if (!empty($placesGeneralResults)) { $data = new ViewBag(); $nb_found = $placesGeneralResults['knownsum']; $nb_other = 0; if (isset($placesGeneralResults['other'])) { $nb_other = $placesGeneralResults['other']; } $nb_unknown = $placesGeneralResults['unknown']; $data->set('stats_gen_nb_found', $nb_found); $data->set('stats_gen_nb_other', $nb_other); $data->set('stats_gen_nb_unknown', $nb_unknown); $data->set('use_flags', $ga->getOptions() && $ga->getOptions()->isUsingFlags()); if ($ga->hasMap()) { $max = $placesGeneralResults['max']; $map = $ga->getOptions()->getMap(); $results_by_subdivs = $map->getSubdivisions(); $places_mappings = $map->getPlacesMappings(); foreach ($placesGeneralResults['places'] as $location => $count) { $levelvalues = array_reverse(array_map('trim', explode(',', $location))); $level_map = $ga->getAnalysisLevel() - $ga->getOptions()->getMapLevel(); if ($level_map >= 0 && $level_map < count($levelvalues)) { $levelref = $levelvalues[0] . '@' . $levelvalues[$level_map]; if (!isset($results_by_subdivs[$levelref])) { $levelref = $levelvalues[0]; } } else { $levelref = $levelvalues[0]; } if (isset($places_mappings[$levelref])) { $levelref = $places_mappings[$levelref]; } if (isset($results_by_subdivs[$levelref])) { $count_subd = isset($results_by_subdivs[$levelref]['count']) ? $results_by_subdivs[$levelref]['count'] : 0; $count_subd += $count; $results_by_subdivs[$levelref]['count'] = $count_subd; $results_by_subdivs[$levelref]['transparency'] = Functions::safeDivision($count_subd, $max); if ($ga->getOptions()->isUsingFlags() && $flags) { $results_by_subdivs[$levelref]['place'] = new Place($location, $WT_TREE); $results_by_subdivs[$levelref]['flag'] = $flags[$location]; } } } $data->set('map', $ga->getOptions()->getMap()); $data->set('results_by_subdivisions', $results_by_subdivs); $html = ViewFactory::make('GeoAnalysisTabGeneralMap', $this, new BaseController(), $data)->getHtmlPartial(); } else { $results = $placesGeneralResults['places']; arsort($results); $data->set('results', $results); $data->set('analysis_level', $ga->getAnalysisLevel()); $html = ViewFactory::make('GeoAnalysisTabGeneralTable', $this, new BaseController(), $data)->getHtmlPartial(); } } else { $html = '<p class="warning">' . I18N::translate('No data is available for the general analysis.') . '</p>'; } return $html; }
/** * Certificate@listAll */ public function listAll() { global $WT_TREE; $controller = new PageController(); $controller->setPageTitle(I18N::translate('Certificates'))->restrictAccess($this->module->getSetting('MAJ_SHOW_CERT', Auth::PRIV_HIDE) >= Auth::accessLevel($WT_TREE)); $city = Filter::get('city'); if (!empty($city) && strlen($city) > 22) { $city = Functions::decryptFromSafeBase64($city); $controller->setPageTitle(I18N::translate('Certificates for %s', $city)); } $data = new ViewBag(); $data->set('title', $controller->getPageTitle()); $data->set('url_module', $this->module->getName()); $data->set('url_action', 'Certificate@listAll'); $data->set('url_ged', $WT_TREE->getNameUrl()); $data->set('cities', $this->provider->getCitiesList()); $data->set('selected_city', $city); $data->set('has_list', false); if (!empty($city)) { $table_id = 'table-certiflist-' . Uuid::uuid4(); $certif_list = $this->provider->getCertificatesList($city); if (!empty($certif_list)) { $data->set('has_list', true); $data->set('table_id', $table_id); $data->set('certificate_list', $certif_list); $controller->addExternalJavascript(WT_JQUERY_DATATABLES_JS_URL)->addInlineJavascript(' /* Initialise datatables */ jQuery.fn.dataTableExt.oSort["unicode-asc" ]=function(a,b) {return a.replace(/<[^<]*>/, "").localeCompare(b.replace(/<[^<]*>/, ""))}; jQuery.fn.dataTableExt.oSort["unicode-desc" ]=function(a,b) {return b.replace(/<[^<]*>/, "").localeCompare(a.replace(/<[^<]*>/, ""))}; jQuery.fn.dataTableExt.oSort["num-html-asc" ]=function(a,b) {a=parseFloat(a.replace(/<[^<]*>/, "")); b=parseFloat(b.replace(/<[^<]*>/, "")); return (a<b) ? -1 : (a>b ? 1 : 0);}; jQuery.fn.dataTableExt.oSort["num-html-desc"]=function(a,b) {a=parseFloat(a.replace(/<[^<]*>/, "")); b=parseFloat(b.replace(/<[^<]*>/, "")); return (a>b) ? -1 : (a<b ? 1 : 0);}; jQuery("#' . $table_id . '").dataTable( { dom: \'<"H"<"filtersH_' . $table_id . '">T<"dt-clear">pf<"dt-clear">irl>t<"F"pl<"dt-clear"><"filtersF_' . $table_id . '">>\', ' . I18N::datatablesI18N() . ', jQueryUI: true, autoWidth: false, processing: true, columns: [ /* 0-Date */ { dataSort: 1, width: "15%", class: "center" }, /* 1-DateSort */ { type: "unicode", visible : false }, /* 2-Type */ { width: "5%", searchable: false, class: "center"}, /* 3-CertificateSort */ { type: "unicode", visible : false }, /* 4-Certificate */ { dataSort: 3, class: "left" } ], sorting: [[0,"asc"], [2,"asc"]], displayLength: 20, pagingType: "full_numbers" }); jQuery(".certificate-list").css("visibility", "visible"); jQuery(".loading-image").css("display", "none"); '); } } ViewFactory::make('CertificatesList', $this, $controller, $data)->render(); }
/** * AdminConfig@generateToken * * Ajax call to generate a new token. Display the token, if generated. * Tokens call only be generated by a site administrator. * */ public function generateToken() { $controller = new AjaxController(); $controller->restrictAccess(Auth::isAdmin()); $token = Functions::generateRandomToken(); $this->module->setSetting('MAJ_AT_FORCE_EXEC_TOKEN', $token); Log::addConfigurationLog($this->module->getTitle() . ' : New token generated.'); $controller->pageHeader(); echo $token; }
/** * Insert (or update if already existing) a list of Sosa individuals * @param array $sosa_records */ public function insertOrUpdate($sosa_records) { if (!$this->is_setup) { return; } $treeid = $this->tree->getTreeId(); $userid = $this->user->getUserId(); $questionmarks_table = array(); $values_table = array(); $i = 0; foreach ($sosa_records as $row) { $gen = Functions::getGeneration($row['sosa']); if ($gen <= self::MAX_DB_GENERATIONS) { $questionmarks_table[] = '(:tree_id' . $i . ', :user_id' . $i . ', :sosa' . $i . ', :indi_id' . $i . ', :gen' . $i . ', :byear' . $i . ', :dyear' . $i . ')'; $values_table = array_merge($values_table, array('tree_id' . $i => $treeid, 'user_id' . $i => $userid, 'sosa' . $i => $row['sosa'], 'indi_id' . $i => $row['indi'], 'gen' . $i => Functions::getGeneration($row['sosa']), 'byear' . $i => $row['birth_year'], 'dyear' . $i => $row['death_year'])); } $i++; } $sql = 'REPLACE INTO `##maj_sosa`' . ' (majs_gedcom_id, majs_user_id, majs_sosa, majs_i_id, majs_gen, majs_birth_year, majs_death_year)' . ' VALUES ' . implode(',', $questionmarks_table); Database::prepare($sql)->execute($values_table); }
/** * {@inheritDoc} * @see \MyArtJaub\Webtrees\Module\GeoDispersion\Views\AbstractGeoAnalysisTabGeneralView::htmlAnalysisData() */ protected function htmlAnalysisData() { /** @var OutlineMap $map */ $map = $this->data->get('map'); $canvas = $map->getCanvas(); $subdvisions_results = $this->data->get('results_by_subdivisions'); $nb_found = $this->data->get('stats_gen_nb_found'); $nb_other = $this->data->get('stats_gen_nb_other'); $html = '<script> var tip = null; var tipText = ""; var over = false; var isin = false; function addTip(node, txt){ jQuery(node).bind({ mouseover : function(){ oldisin = isin; isin = true; if(oldisin != isin){ tipText = txt; tip.stop(true, true).fadeIn(); over = true; } }, mouseout : function(){ oldisin = isin; isin = false; if(oldisin != isin){ tip.stop(true, true).fadeOut("fast"); over = false; } } }); } jQuery(document).ready(function() { tip = $("#geodispersion_tip").hide(); var positionTab = jQuery("#geodispersion-tabs").offset(); jQuery("#geodispersion_map").mousemove(function(e){ if (over){ tip.css("left", e.pageX + 20 - positionTab.left).css("top", e.pageY + 20 - positionTab.top); tip.html(tipText); } }); var paper = new Raphael(document.getElementById("geodispersion_map"), ' . $canvas->width . ', ' . $canvas->height . '); var background = paper.rect(0, 0, ' . $canvas->width . ', ' . $canvas->height . '); background.attr({"fill" : "' . $canvas->background_color . '", "stroke" : "' . $canvas->background_stroke . '", "stroke-width": 1, "stroke-linejoin": "round" }); var attr = { fill: "' . $canvas->default_color . '", stroke: "' . $canvas->default_stroke . '", "stroke-width": 1, "stroke-linejoin": "round" }; var map = {}; '; foreach ($subdvisions_results as $name => $location) { $html .= 'map.area' . $location['id'] . ' = paper.path("' . $location['coord'] . '").attr(attr);'; if (isset($location['transparency'])) { $textToolTip = '<strong>' . $location['displayname'] . '</strong><br/>'; if ($this->data->get('use_flags') && $location['flag'] != '') { $textToolTip .= '<span class="geodispersion_flag">' . FunctionsPrint::htmlPlaceIcon($location['place'], $location['flag']) . '</span><br/>'; } $textToolTip .= I18N::translate('%d individuals', $location['count']) . '<br/>' . I18N::percentage(Functions::safeDivision($location['count'], $nb_found - $nb_other), 1); $html .= 'addTip(map.area' . $location['id'] . '.node, "' . Filter::escapeJs($textToolTip) . '");'; $html .= 'map.area' . $location['id'] . '.attr({"fill" : "' . $canvas->max_color . '", "fill-opacity" : ' . $location['transparency'] . ' });'; $html .= 'map.area' . $location['id'] . '.mouseover(function () {' . 'map.area' . $location['id'] . '.stop().animate({"fill" : "' . $canvas->hover_color . '", "fill-opacity" : 1}, 100, "linear");' . '});' . 'map.area' . $location['id'] . '.mouseout(function () {' . 'map.area' . $location['id'] . '.stop().animate({"fill" : "' . $canvas->max_color . '", "fill-opacity" : ' . $location['transparency'] . '}, 100, "linear");' . '});'; } } $html .= '}); </script> <div id="geodispersion_map"></div> <div id="geodispersion_tip"></div>'; return $html; }
/** * Returns the HTML code fo display a row of the Top Places found for a generation. * * @param array $data Data array * @param int $analysis_level Level of subdivision of analysis * @return string HTML code for Top Places row */ protected function htmlGenerationTopPlacesRow($data, $analysis_level) { $tmp_places = array(); $sum_gen = $data['sum']; $other = $data['other']; foreach ($data['places'] as $placename => $count) { if ($placename != 'other') { $levels = array_map('trim', explode(',', $placename)); $placename = '<span title="' . implode(I18N::$list_separator, array_reverse($levels)) . '">' . $levels[$analysis_level - 1] . '</span>'; } else { $placename = I18N::translate('Other places'); } $tmp_places[] = I18N::translate('<strong>%s</strong> [%d - %s]', $placename, $count, I18N::percentage(Functions::safeDivision($count, $sum_gen + $other), 1)); } return implode(I18N::$list_separator, $tmp_places); }