diff options
| author | Greg Roach <fisharebest@webtrees.net> | 2019-01-22 18:33:47 +0000 |
|---|---|---|
| committer | Greg Roach <fisharebest@webtrees.net> | 2019-01-22 18:33:47 +0000 |
| commit | eca4a663f165bdb661e38d8684adc333ae7fdc22 (patch) | |
| tree | 3033c1905a1013726eb917d56d2d77a551b6c008 | |
| parent | 241a1636dee0487eb56818cbf3b6a79ceaf02090 (diff) | |
| download | webtrees-eca4a663f165bdb661e38d8684adc333ae7fdc22.tar.gz webtrees-eca4a663f165bdb661e38d8684adc333ae7fdc22.tar.bz2 webtrees-eca4a663f165bdb661e38d8684adc333ae7fdc22.zip | |
Merge chart controllers into chart modules
| -rw-r--r-- | app/Http/Controllers/TimelineChartController.php | 251 | ||||
| -rw-r--r-- | app/Module/TimelineChartModule.php | 231 | ||||
| -rw-r--r-- | resources/views/modules/timeline-chart/chart-page.phtml (renamed from resources/views/timeline-page.phtml) | 8 | ||||
| -rw-r--r-- | resources/views/modules/timeline-chart/chart.phtml (renamed from resources/views/timeline-chart.phtml) | 0 | ||||
| -rw-r--r-- | routes/web.php | 2 |
5 files changed, 232 insertions, 260 deletions
diff --git a/app/Http/Controllers/TimelineChartController.php b/app/Http/Controllers/TimelineChartController.php deleted file mode 100644 index 6564be5213..0000000000 --- a/app/Http/Controllers/TimelineChartController.php +++ /dev/null @@ -1,251 +0,0 @@ -<?php -/** - * webtrees: online genealogy - * Copyright (C) 2019 webtrees development team - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * This program is distributed in the hope that it will be useful, - * 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/>. - */ -declare(strict_types=1); - -namespace Fisharebest\Webtrees\Http\Controllers; - -use Fisharebest\Webtrees\Date\GregorianDate; -use Fisharebest\Webtrees\Functions\Functions; -use Fisharebest\Webtrees\I18N; -use Fisharebest\Webtrees\Individual; -use Fisharebest\Webtrees\Module\TimelineChartModule; -use Fisharebest\Webtrees\Tree; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; - -/** - * A chart showing the events of individuals on a time line. - */ -class TimelineChartController extends AbstractBaseController -{ - // The user can alter the vertical scale - private const SCALE_MIN = 1; - private const SCALE_MAX = 200; - private const SCALE_DEFAULT = 10; - - // GEDCOM events that may have DATE data, but should not be displayed - private const NON_FACTS = [ - 'BAPL', - 'ENDL', - 'SLGC', - 'SLGS', - '_TODO', - 'CHAN', - ]; - - // Box height - private const BHEIGHT = 30; - - /** - * A form to request the chart parameters. - * - * @param Request $request - * @param Tree $tree - * - * @return Response - */ - public function page(Request $request, Tree $tree): Response - { - $this->checkModuleIsActive($tree, TimelineChartModule::class); - - $scale = (int) $request->get('scale', self::SCALE_DEFAULT); - $scale = min($scale, self::SCALE_MAX); - $scale = max($scale, self::SCALE_MIN); - - $xrefs = (array) $request->get('xrefs', []); - - // Find the requested individuals. - $individuals = array_map(function (string $xref) use ($tree) { - return Individual::getInstance($xref, $tree); - }, $xrefs); - - $individuals = array_filter($individuals, function (Individual $individual = null) { - return $individual instanceof Individual && $individual->canShow(); - }); - - // Generate URLs omitting each xref. - $remove_urls = []; - foreach ($individuals as $individual) { - $tmp = $this->allXrefsExceptOne($individual, $individuals); - - $remove_urls[$individual->xref()] = route('timeline', [ - 'ged' => $tree->name(), - 'scale' => $scale, - 'xrefs' => $tmp, - ]); - } - - $individuals = array_map(function (string $xref) use ($tree) { - return Individual::getInstance($xref, $tree); - }, $xrefs); - - $title = I18N::translate('Timeline'); - - $chart_url = route('timeline-chart', [ - 'ged' => $tree->name(), - 'scale' => $scale, - 'xrefs' => $xrefs, - ]); - - $zoom_in_url = route('timeline', [ - 'ged' => $tree->name(), - 'scale' => min(self::SCALE_MAX, $scale + (int) ($scale * 0.2 + 1)), - 'xrefs' => $xrefs, - ]); - - $zoom_out_url = route('timeline', [ - 'route' => 'timeline', - 'ged' => $tree->name(), - 'scale' => max(self::SCALE_MIN, $scale - (int) ($scale * 0.2 + 1)), - 'xrefs' => $xrefs, - ]); - - return $this->viewResponse('timeline-page', [ - 'chart_url' => $chart_url, - 'individuals' => $individuals, - 'remove_urls' => $remove_urls, - 'title' => $title, - 'scale' => $scale, - 'zoom_in_url' => $zoom_in_url, - 'zoom_out_url' => $zoom_out_url, - ]); - } - - /** - * @param Request $request - * @param Tree $tree - * - * @return Response - */ - public function chart(Request $request, Tree $tree): Response - { - $this->checkModuleIsActive($tree, TimelineChartModule::class); - - $scale = (int) $request->get('scale', self::SCALE_DEFAULT); - $scale = min($scale, self::SCALE_MAX); - $scale = max($scale, self::SCALE_MIN); - - $xrefs = (array) $request->get('xrefs', []); - $xrefs = array_unique($xrefs); - - /** @var Individual[] $individuals */ - $individuals = array_map(function (string $xref) use ($tree) { - return Individual::getInstance($xref, $tree); - }, $xrefs); - - $individuals = array_filter($individuals, function (Individual $individual = null): bool { - return $individual !== null && $individual->canShow(); - }); - - $baseyear = (int) date('Y'); - $topyear = 0; - $indifacts = []; - $birthyears = []; - $birthmonths = []; - $birthdays = []; - - foreach ($individuals as $individual) { - $bdate = $individual->getBirthDate(); - if ($bdate->isOK()) { - $date = new GregorianDate($bdate->minimumJulianDay()); - - $birthyears [$individual->xref()] = $date->year; - $birthmonths[$individual->xref()] = max(1, $date->month); - $birthdays [$individual->xref()] = max(1, $date->day); - } - // find all the fact information - $facts = $individual->facts(); - foreach ($individual->getSpouseFamilies() as $family) { - foreach ($family->facts() as $fact) { - $facts[] = $fact; - } - } - foreach ($facts as $event) { - // get the fact type - $fact = $event->getTag(); - if (!in_array($fact, self::NON_FACTS)) { - // check for a date - $date = $event->date(); - if ($date->isOK()) { - $date = new GregorianDate($date->minimumJulianDay()); - $baseyear = min($baseyear, $date->year); - $topyear = max($topyear, $date->year); - - if (!$individual->isDead()) { - $topyear = max($topyear, (int) date('Y')); - } - - // do not add the same fact twice (prevents marriages from being added multiple times) - if (!in_array($event, $indifacts, true)) { - $indifacts[] = $event; - } - } - } - } - } - - if ($scale === 0) { - $scale = (int) (($topyear - $baseyear) / 20 * count($indifacts) / 4); - if ($scale < 6) { - $scale = 6; - } - } - if ($scale < 2) { - $scale = 2; - } - $baseyear -= 5; - $topyear += 5; - - Functions::sortFacts($indifacts); - - $html = view('timeline-chart', [ - 'baseyear' => $baseyear, - 'bheight' => self::BHEIGHT, - 'birthdays' => $birthdays, - 'birthmonths' => $birthmonths, - 'birthyears' => $birthyears, - 'indifacts' => $indifacts, - 'individuals' => $individuals, - 'placements' => [], - 'scale' => $scale, - 'topyear' => $topyear, - ]); - - return new Response($html); - } - - /** - * Take a list of individuals, and generate a list of XREFs that includes all - * except a specified one. - * - * @param Individual $individual - * @param Individual[] $individuals - * - * @return array - */ - private function allXrefsExceptOne(Individual $individual, array $individuals): array - { - $xrefs = array_map(function (Individual $individual) { - return $individual->xref(); - }, $individuals); - - $xrefs = array_filter($xrefs, function (string $xref) use ($individual) { - return $xref !== $individual->xref(); - }); - - return $xrefs; - } -} diff --git a/app/Module/TimelineChartModule.php b/app/Module/TimelineChartModule.php index a248faaedb..4f8174507b 100644 --- a/app/Module/TimelineChartModule.php +++ b/app/Module/TimelineChartModule.php @@ -17,8 +17,15 @@ declare(strict_types=1); namespace Fisharebest\Webtrees\Module; +use Fisharebest\Webtrees\Date\GregorianDate; +use Fisharebest\Webtrees\Functions\Functions; +use Fisharebest\Webtrees\GedcomRecord; use Fisharebest\Webtrees\I18N; use Fisharebest\Webtrees\Individual; +use Fisharebest\Webtrees\Tree; +use Illuminate\Support\Collection; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; /** * Class TimelineChartModule @@ -27,6 +34,24 @@ class TimelineChartModule extends AbstractModule implements ModuleInterface, Mod { use ModuleChartTrait; + // The user can alter the vertical scale + protected const SCALE_MIN = 1; + protected const SCALE_MAX = 200; + protected const SCALE_DEFAULT = 10; + + // GEDCOM events that may have DATE data, but should not be displayed + protected const NON_FACTS = [ + 'BAPL', + 'ENDL', + 'SLGC', + 'SLGS', + '_TODO', + 'CHAN', + ]; + + // Box height + protected const BHEIGHT = 30; + /** * How should this module be labelled on tabs, menus, etc.? * @@ -69,9 +94,207 @@ class TimelineChartModule extends AbstractModule implements ModuleInterface, Mod */ public function chartUrl(Individual $individual, array $parameters = []): string { - return route('timeline', [ - 'xrefs[]' => $individual->xref(), - 'ged' => $individual->tree()->name(), - ] + $parameters); + return route('module', [ + 'module' => $this->name(), + 'action' => 'Chart', + 'xrefs[]' => $individual->xref(), + 'ged' => $individual->tree()->name(), + ] + $parameters); + } + + /** + * A form to request the chart parameters. + * + * @param Request $request + * @param Tree $tree + * + * @return Response + */ + public function getChartAction(Request $request, Tree $tree): Response + { + $ajax = $request->get('ajax'); + $scale = (int) $request->get('scale', self::SCALE_DEFAULT); + $scale = min($scale, self::SCALE_MAX); + $scale = max($scale, self::SCALE_MIN); + + $xrefs = $request->get('xrefs', []); + + // Find the requested individuals. + $individuals = (new Collection($xrefs)) + ->unique() + ->map(function (string $xref) use ($tree): ?Individual { + return Individual::getInstance($xref, $tree); + }) + ->filter() + ->filter(GedcomRecord::accessFilter()); + + // Generate URLs omitting each xref. + $remove_urls = []; + + foreach ($individuals as $exclude) { + $xrefs_1 = $individuals + ->filter(function (Individual $individual) use ($exclude): bool { + return $individual->xref() !== $exclude->xref(); + }) + ->map(function (Individual $individual): string { + return $individual->xref(); + }); + + $remove_urls[$exclude->xref()] = route('module', [ + 'module' => $this->name(), + 'action' => 'Chart', + 'ged' => $tree->name(), + 'scale' => $scale, + 'xrefs' => $xrefs_1->all(), + ]); + } + + $individuals = array_map(function (string $xref) use ($tree) { + return Individual::getInstance($xref, $tree); + }, $xrefs); + + if ($ajax === '1') { + return $this->chart($tree, $xrefs, $scale); + } + + $ajax_url = route('module', [ + 'ajax' => '1', + 'module' => $this->name(), + 'action' => 'Chart', + 'ged' => $tree->name(), + 'scale' => $scale, + 'xrefs' => $xrefs, + ]); + + $reset_url = route('module', [ + 'module' => $this->name(), + 'action' => 'Chart', + 'ged' => $tree->name(), + ]); + + $zoom_in_url = route('module', [ + 'module' => $this->name(), + 'action' => 'Chart', + 'ged' => $tree->name(), + 'scale' => min(self::SCALE_MAX, $scale + (int) ($scale * 0.2 + 1)), + 'xrefs' => $xrefs, + ]); + + $zoom_out_url = route('module', [ + 'module' => $this->name(), + 'action' => 'Chart', + 'ged' => $tree->name(), + 'scale' => max(self::SCALE_MIN, $scale - (int) ($scale * 0.2 + 1)), + 'xrefs' => $xrefs, + ]); + + return $this->viewResponse('modules/timeline-chart/chart-page', [ + 'ajax_url' => $ajax_url, + 'individuals' => $individuals, + 'module_name' => $this->name(), + 'remove_urls' => $remove_urls, + 'reset_url' => $reset_url, + 'title' => $this->title(), + 'scale' => $scale, + 'zoom_in_url' => $zoom_in_url, + 'zoom_out_url' => $zoom_out_url, + ]); + } + + /** + * @param Tree $tree + * @param array $xrefs + * @param int $scale + * + * @return Response + */ + protected function chart(Tree $tree, array $xrefs, int $scale): Response + { + $xrefs = array_unique($xrefs); + + /** @var Individual[] $individuals */ + $individuals = array_map(function (string $xref) use ($tree) { + return Individual::getInstance($xref, $tree); + }, $xrefs); + + $individuals = array_filter($individuals, function (Individual $individual = null): bool { + return $individual !== null && $individual->canShow(); + }); + + $baseyear = (int) date('Y'); + $topyear = 0; + $indifacts = []; + $birthyears = []; + $birthmonths = []; + $birthdays = []; + + foreach ($individuals as $individual) { + $bdate = $individual->getBirthDate(); + if ($bdate->isOK()) { + $date = new GregorianDate($bdate->minimumJulianDay()); + + $birthyears [$individual->xref()] = $date->year; + $birthmonths[$individual->xref()] = max(1, $date->month); + $birthdays [$individual->xref()] = max(1, $date->day); + } + // find all the fact information + $facts = $individual->facts(); + foreach ($individual->getSpouseFamilies() as $family) { + foreach ($family->facts() as $fact) { + $facts[] = $fact; + } + } + foreach ($facts as $event) { + // get the fact type + $fact = $event->getTag(); + if (!in_array($fact, self::NON_FACTS)) { + // check for a date + $date = $event->date(); + if ($date->isOK()) { + $date = new GregorianDate($date->minimumJulianDay()); + $baseyear = min($baseyear, $date->year); + $topyear = max($topyear, $date->year); + + if (!$individual->isDead()) { + $topyear = max($topyear, (int) date('Y')); + } + + // do not add the same fact twice (prevents marriages from being added multiple times) + if (!in_array($event, $indifacts, true)) { + $indifacts[] = $event; + } + } + } + } + } + + if ($scale === 0) { + $scale = (int) (($topyear - $baseyear) / 20 * count($indifacts) / 4); + if ($scale < 6) { + $scale = 6; + } + } + if ($scale < 2) { + $scale = 2; + } + $baseyear -= 5; + $topyear += 5; + + Functions::sortFacts($indifacts); + + $html = view('modules/timeline-chart/chart', [ + 'baseyear' => $baseyear, + 'bheight' => self::BHEIGHT, + 'birthdays' => $birthdays, + 'birthmonths' => $birthmonths, + 'birthyears' => $birthyears, + 'indifacts' => $indifacts, + 'individuals' => $individuals, + 'placements' => [], + 'scale' => $scale, + 'topyear' => $topyear, + ]); + + return new Response($html); } } diff --git a/resources/views/timeline-page.phtml b/resources/views/modules/timeline-chart/chart-page.phtml index 6ff55313de..bdef28cd80 100644 --- a/resources/views/timeline-page.phtml +++ b/resources/views/modules/timeline-chart/chart-page.phtml @@ -6,7 +6,9 @@ </h2> <form class="wt-page-options wt-page-options-timeline-chart d-print-none"> - <input type="hidden" name="route" value="timeline"> + <input type="hidden" name="route" value="module"> + <input type="hidden" name="module" value="<?= e($module_name) ?>"> + <input type="hidden" name="action" value="Chart"> <input type="hidden" name="ged" value="<?= e($tree->name()) ?>"> <input type="hidden" name="scale" value="<?= e($scale) ?>"> @@ -31,7 +33,7 @@ <div class="col-sm-9 wt-page-options-value"> <input class="btn btn-primary" type="submit" value="<?= /* I18N: A button label. */ I18N::translate('add') ?>"> - <a class="btn btn-secondary" href="<?= e(route('timeline', ['ged' => $tree->name()])) ?>"> + <a class="btn btn-secondary" href="<?= e($reset_url) ?>"> <?= /* I18N: A button label. */ I18N::translate('reset') ?> </a> </div> @@ -71,4 +73,4 @@ <?php endforeach ?> </div> -<div class="wt-ajax-load wt-page-content wt-chart wt-timeline-chart" data-ajax-url="<?= e($chart_url) ?>"></div> +<div class="wt-ajax-load wt-page-content wt-chart wt-timeline-chart" data-ajax-url="<?= e($ajax_url) ?>"></div> diff --git a/resources/views/timeline-chart.phtml b/resources/views/modules/timeline-chart/chart.phtml index 3cc349edeb..3cc349edeb 100644 --- a/resources/views/timeline-chart.phtml +++ b/resources/views/modules/timeline-chart/chart.phtml diff --git a/routes/web.php b/routes/web.php index b25604edc2..acb8438ab9 100644 --- a/routes/web.php +++ b/routes/web.php @@ -286,8 +286,6 @@ if ($tree instanceof Tree && $tree->getPreference('imported') === '1') { 'GET:statistics-other' => 'StatisticsChartController@chartOther', 'GET:statistics-options' => 'StatisticsChartController@chartCustomOptions', 'GET:statistics-chart' => 'StatisticsChartController@chartCustomChart', - 'GET:timeline' => 'TimelineChartController@page', - 'GET:timeline-chart' => 'TimelineChartController@chart', 'POST:accept-changes' => 'PendingChangesController@acceptChanges', 'POST:reject-changes' => 'PendingChangesController@rejectChanges', 'POST:accept-all-changes' => 'PendingChangesController@acceptAllChanges', |
