summaryrefslogtreecommitdiff
path: root/app/Http/Controllers/DescendantsChartController.php
diff options
context:
space:
mode:
Diffstat (limited to 'app/Http/Controllers/DescendantsChartController.php')
-rw-r--r--app/Http/Controllers/DescendantsChartController.php640
1 files changed, 330 insertions, 310 deletions
diff --git a/app/Http/Controllers/DescendantsChartController.php b/app/Http/Controllers/DescendantsChartController.php
index 69a929917a..613b7da78b 100644
--- a/app/Http/Controllers/DescendantsChartController.php
+++ b/app/Http/Controllers/DescendantsChartController.php
@@ -33,358 +33,378 @@ use Symfony\Component\HttpFoundation\Response;
/**
* A chart of direct-line descendants.
*/
-class DescendantsChartController extends AbstractChartController {
- // Chart styles
- const CHART_STYLE_LIST = 0;
- const CHART_STYLE_BOOKLET = 1;
- const CHART_STYLE_INDIVIDUALS = 2;
- const CHART_STYLE_FAMILIES = 3;
+class DescendantsChartController extends AbstractChartController
+{
+ // Chart styles
+ const CHART_STYLE_LIST = 0;
+ const CHART_STYLE_BOOKLET = 1;
+ const CHART_STYLE_INDIVIDUALS = 2;
+ const CHART_STYLE_FAMILIES = 3;
- // Defaults
- const DEFAULT_STYLE = self::CHART_STYLE_LIST;
- const DEFAULT_GENERATIONS = 3;
- const DEFAULT_MAXIMUM_GENERATIONS = 9;
+ // Defaults
+ const DEFAULT_STYLE = self::CHART_STYLE_LIST;
+ const DEFAULT_GENERATIONS = 3;
+ const DEFAULT_MAXIMUM_GENERATIONS = 9;
- protected $dabo_num = [];
- protected $dabo_sex = [];
+ protected $dabo_num = [];
+ protected $dabo_sex = [];
- /**
- * A form to request the chart parameters.
- *
- * @param Request $request
- *
- * @return Response
- */
- public function page(Request $request): Response {
- /** @var Tree $tree */
- $tree = $request->attributes->get('tree');
+ /**
+ * A form to request the chart parameters.
+ *
+ * @param Request $request
+ *
+ * @return Response
+ */
+ public function page(Request $request): Response
+ {
+ /** @var Tree $tree */
+ $tree = $request->attributes->get('tree');
- $this->checkModuleIsActive($tree, 'descendancy_chart');
+ $this->checkModuleIsActive($tree, 'descendancy_chart');
- $xref = $request->get('xref');
- $individual = Individual::getInstance($xref, $tree);
+ $xref = $request->get('xref');
+ $individual = Individual::getInstance($xref, $tree);
- $minimum_generations = 2;
- $maximum_generations = (int) $tree->getPreference('MAX_DESCENDANCY_GENERATIONS', self::DEFAULT_MAXIMUM_GENERATIONS);
- $default_generations = (int) $tree->getPreference('DEFAULT_PEDIGREE_GENERATIONS', self::DEFAULT_GENERATIONS);
+ $minimum_generations = 2;
+ $maximum_generations = (int)$tree->getPreference('MAX_DESCENDANCY_GENERATIONS', self::DEFAULT_MAXIMUM_GENERATIONS);
+ $default_generations = (int)$tree->getPreference('DEFAULT_PEDIGREE_GENERATIONS', self::DEFAULT_GENERATIONS);
- $chart_style = (int) $request->get('chart_style', self::DEFAULT_STYLE);
- $generations = (int) $request->get('generations', $default_generations);
+ $chart_style = (int)$request->get('chart_style', self::DEFAULT_STYLE);
+ $generations = (int)$request->get('generations', $default_generations);
- $generations = min($generations, $maximum_generations);
- $generations = max($generations, $minimum_generations);
+ $generations = min($generations, $maximum_generations);
+ $generations = max($generations, $minimum_generations);
- if ($individual !== null && $individual->canShowName()) {
- $title = /* I18N: %s is an individual’s name */ I18N::translate('Descendants of %s', $individual->getFullName());
- } else {
- $title = I18N::translate('Descendants');
- }
+ if ($individual !== null && $individual->canShowName()) {
+ $title = /* I18N: %s is an individual’s name */
+ I18N::translate('Descendants of %s', $individual->getFullName());
+ } else {
+ $title = I18N::translate('Descendants');
+ }
- return $this->viewResponse('descendants-page', [
- 'chart_style' => $chart_style,
- 'chart_styles' => $this->chartStyles(),
- 'default_generations' => $default_generations,
- 'generations' => $generations,
- 'individual' => $individual,
- 'maximum_generations' => $maximum_generations,
- 'minimum_generations' => $minimum_generations,
- 'title' => $title,
- ]);
- }
+ return $this->viewResponse('descendants-page', [
+ 'chart_style' => $chart_style,
+ 'chart_styles' => $this->chartStyles(),
+ 'default_generations' => $default_generations,
+ 'generations' => $generations,
+ 'individual' => $individual,
+ 'maximum_generations' => $maximum_generations,
+ 'minimum_generations' => $minimum_generations,
+ 'title' => $title,
+ ]);
+ }
- /**
- * @param Request $request
- *
- * @return Response
- */
- public function chart(Request $request): Response {
- /** @var Tree $tree */
- $tree = $request->attributes->get('tree');
+ /**
+ * @param Request $request
+ *
+ * @return Response
+ */
+ public function chart(Request $request): Response
+ {
+ /** @var Tree $tree */
+ $tree = $request->attributes->get('tree');
- $this->checkModuleIsActive($tree, 'descendancy_chart');
+ $this->checkModuleIsActive($tree, 'descendancy_chart');
- $xref = $request->get('xref');
- $individual = Individual::getInstance($xref, $tree);
+ $xref = $request->get('xref');
+ $individual = Individual::getInstance($xref, $tree);
- $this->checkIndividualAccess($individual);
+ $this->checkIndividualAccess($individual);
- $minimum_generations = 2;
- $maximum_generations = (int) $tree->getPreference('MAX_PEDIGREE_GENERATIONS', self::DEFAULT_MAXIMUM_GENERATIONS);
- $default_generations = (int) $tree->getPreference('DEFAULT_PEDIGREE_GENERATIONS', self::DEFAULT_GENERATIONS);
+ $minimum_generations = 2;
+ $maximum_generations = (int)$tree->getPreference('MAX_PEDIGREE_GENERATIONS', self::DEFAULT_MAXIMUM_GENERATIONS);
+ $default_generations = (int)$tree->getPreference('DEFAULT_PEDIGREE_GENERATIONS', self::DEFAULT_GENERATIONS);
- $chart_style = (int) $request->get('chart_style', self::DEFAULT_STYLE);
- $generations = (int) $request->get('generations', $default_generations);
+ $chart_style = (int)$request->get('chart_style', self::DEFAULT_STYLE);
+ $generations = (int)$request->get('generations', $default_generations);
- $generations = min($generations, $maximum_generations);
- $generations = max($generations, $minimum_generations);
+ $generations = min($generations, $maximum_generations);
+ $generations = max($generations, $minimum_generations);
- $descendants = $this->descendants($individual, $generations, []);
+ $descendants = $this->descendants($individual, $generations, []);
- switch($chart_style) {
- case self::CHART_STYLE_LIST:
- default:
- return $this->descendantsList($individual, $generations);
- case self::CHART_STYLE_BOOKLET:
- return $this->descendantsBooklet($individual, $generations);
- case self::CHART_STYLE_INDIVIDUALS:
- return $this->descendantsIndividuals($tree, $descendants);
- case self::CHART_STYLE_FAMILIES:
- return $this->descendantsFamilies($tree, $descendants);
- }
- }
+ switch ($chart_style) {
+ case self::CHART_STYLE_LIST:
+ default:
+ return $this->descendantsList($individual, $generations);
+ case self::CHART_STYLE_BOOKLET:
+ return $this->descendantsBooklet($individual, $generations);
+ case self::CHART_STYLE_INDIVIDUALS:
+ return $this->descendantsIndividuals($tree, $descendants);
+ case self::CHART_STYLE_FAMILIES:
+ return $this->descendantsFamilies($tree, $descendants);
+ }
+ }
- /**
- * Show a hierarchical list of descendants
- *
- * @TODO replace ob_start() with views.
- *
- * @param Individual $individual
- * @param int $generations
- *
- * @return Response
- */
- private function descendantsList(Individual $individual, int $generations): Response {
- ob_start();
+ /**
+ * Show a hierarchical list of descendants
+ *
+ * @TODO replace ob_start() with views.
+ *
+ * @param Individual $individual
+ * @param int $generations
+ *
+ * @return Response
+ */
+ private function descendantsList(Individual $individual, int $generations): Response
+ {
+ ob_start();
- echo '<ul class="chart_common">';
- $this->printChildDescendancy($individual, $generations, $generations);
- echo '</ul>';
+ echo '<ul class="chart_common">';
+ $this->printChildDescendancy($individual, $generations, $generations);
+ echo '</ul>';
- $html = ob_get_clean();
+ $html = ob_get_clean();
- return new Response($html);
+ return new Response($html);
- }
+ }
- /**
- * print a child descendancy
- *
- * @param Individual $person
- * @param int $depth the descendancy depth to show
- * @param int $generations
- */
- private function printChildDescendancy(Individual $person, $depth, int $generations) {
- echo '<li>';
- echo '<table><tr><td>';
- if ($depth == $generations) {
- echo '<img src="' . Theme::theme()->parameter('image-spacer') . '" height="3" width="15"></td><td>';
- } else {
- echo '<img src="' . Theme::theme()->parameter('image-spacer') . '" height="3" width="3">';
- echo '<img src="' . Theme::theme()->parameter('image-hline') . '" height="3" width="', 12, '"></td><td>';
- }
- FunctionsPrint::printPedigreePerson($person);
- echo '</td>';
+ /**
+ * print a child descendancy
+ *
+ * @param Individual $person
+ * @param int $depth the descendancy depth to show
+ * @param int $generations
+ */
+ private function printChildDescendancy(Individual $person, $depth, int $generations)
+ {
+ echo '<li>';
+ echo '<table><tr><td>';
+ if ($depth == $generations) {
+ echo '<img src="' . Theme::theme()->parameter('image-spacer') . '" height="3" width="15"></td><td>';
+ } else {
+ echo '<img src="' . Theme::theme()->parameter('image-spacer') . '" height="3" width="3">';
+ echo '<img src="' . Theme::theme()->parameter('image-hline') . '" height="3" width="', 12, '"></td><td>';
+ }
+ FunctionsPrint::printPedigreePerson($person);
+ echo '</td>';
- // check if child has parents and add an arrow
- echo '<td></td>';
- echo '<td>';
- foreach ($person->getChildFamilies() as $cfamily) {
- foreach ($cfamily->getSpouses() as $parent) {
- echo FontAwesome::linkIcon('arrow-up', I18N::translate('Start at parents'), ['href' => route('descendants', ['ged' => $parent->getTree()->getName(), 'xref' => $parent->getXref(), 'generations' => $generations])]);
- // only show the arrow for one of the parents
- break;
- }
- }
+ // check if child has parents and add an arrow
+ echo '<td></td>';
+ echo '<td>';
+ foreach ($person->getChildFamilies() as $cfamily) {
+ foreach ($cfamily->getSpouses() as $parent) {
+ echo FontAwesome::linkIcon('arrow-up', I18N::translate('Start at parents'), ['href' => route('descendants', ['ged' => $parent->getTree()->getName(),
+ 'xref' => $parent->getXref(),
+ 'generations' => $generations,
+ ]),
+ ]);
+ // only show the arrow for one of the parents
+ break;
+ }
+ }
- // d'Aboville child number
- $level = $generations - $depth;
- echo '<br><br>&nbsp;';
- echo '<span dir="ltr">'; //needed so that RTL languages will display this properly
- if (!isset($this->dabo_num[$level])) {
- $this->dabo_num[$level] = 0;
- }
- $this->dabo_num[$level]++;
- $this->dabo_num[$level + 1] = 0;
- $this->dabo_sex[$level] = $person->getSex();
- for ($i = 0; $i <= $level; $i++) {
- $isf = $this->dabo_sex[$i];
- if ($isf === 'M') {
- $isf = '';
- }
- if ($isf === 'U') {
- $isf = 'NN';
- }
- echo '<span class="person_box' . $isf . '">&nbsp;' . $this->dabo_num[$i] . '&nbsp;</span>';
- if ($i < $level) {
- echo '.';
- }
- }
- echo '</span>';
- echo '</td></tr>';
- echo '</table>';
- echo '</li>';
+ // d'Aboville child number
+ $level = $generations - $depth;
+ echo '<br><br>&nbsp;';
+ echo '<span dir="ltr">'; //needed so that RTL languages will display this properly
+ if (!isset($this->dabo_num[$level])) {
+ $this->dabo_num[$level] = 0;
+ }
+ $this->dabo_num[$level]++;
+ $this->dabo_num[$level + 1] = 0;
+ $this->dabo_sex[$level] = $person->getSex();
+ for ($i = 0; $i <= $level; $i++) {
+ $isf = $this->dabo_sex[$i];
+ if ($isf === 'M') {
+ $isf = '';
+ }
+ if ($isf === 'U') {
+ $isf = 'NN';
+ }
+ echo '<span class="person_box' . $isf . '">&nbsp;' . $this->dabo_num[$i] . '&nbsp;</span>';
+ if ($i < $level) {
+ echo '.';
+ }
+ }
+ echo '</span>';
+ echo '</td></tr>';
+ echo '</table>';
+ echo '</li>';
- // loop for each spouse
- foreach ($person->getSpouseFamilies() as $family) {
- $this->printFamilyDescendancy($person, $family, $depth, $generations);
- }
- }
+ // loop for each spouse
+ foreach ($person->getSpouseFamilies() as $family) {
+ $this->printFamilyDescendancy($person, $family, $depth, $generations);
+ }
+ }
- /**
- * print a family descendancy
- *
- * @param Individual $person
- * @param Family $family
- * @param int $depth the descendancy depth to show
- * @param int $generations
- */
- private function printFamilyDescendancy(Individual $person, Family $family, int $depth, int $generations) {
- $uid = Uuid::uuid4()->toString(); // create a unique ID
- // print marriage info
- echo '<li>';
- echo '<img src="', Theme::theme()->parameter('image-spacer'), '" height="2" width="', 19, '">';
- echo '<span class="details1">';
- echo '<a href="#" onclick="expand_layer(\'' . $uid . '\'); return false;" class="top"><i id="' . $uid . '_img" class="icon-minus" title="' . I18N::translate('View this family') . '"></i></a>';
- if ($family->canShow()) {
- foreach ($family->getFacts(WT_EVENTS_MARR) as $fact) {
- echo ' <a href="', e($family->url()), '" class="details1">', $fact->summary(), '</a>';
- }
- }
- echo '</span>';
+ /**
+ * print a family descendancy
+ *
+ * @param Individual $person
+ * @param Family $family
+ * @param int $depth the descendancy depth to show
+ * @param int $generations
+ */
+ private function printFamilyDescendancy(Individual $person, Family $family, int $depth, int $generations)
+ {
+ $uid = Uuid::uuid4()->toString(); // create a unique ID
+ // print marriage info
+ echo '<li>';
+ echo '<img src="', Theme::theme()->parameter('image-spacer'), '" height="2" width="', 19, '">';
+ echo '<span class="details1">';
+ echo '<a href="#" onclick="expand_layer(\'' . $uid . '\'); return false;" class="top"><i id="' . $uid . '_img" class="icon-minus" title="' . I18N::translate('View this family') . '"></i></a>';
+ if ($family->canShow()) {
+ foreach ($family->getFacts(WT_EVENTS_MARR) as $fact) {
+ echo ' <a href="', e($family->url()), '" class="details1">', $fact->summary(), '</a>';
+ }
+ }
+ echo '</span>';
- // print spouse
- $spouse = $family->getSpouse($person);
- echo '<ul class="generations" id="' . $uid . '">';
- echo '<li>';
- echo '<table><tr><td>';
- FunctionsPrint::printPedigreePerson($spouse);
- echo '</td>';
+ // print spouse
+ $spouse = $family->getSpouse($person);
+ echo '<ul class="generations" id="' . $uid . '">';
+ echo '<li>';
+ echo '<table><tr><td>';
+ FunctionsPrint::printPedigreePerson($spouse);
+ echo '</td>';
- // check if spouse has parents and add an arrow
- echo '<td></td>';
- echo '<td>';
- if ($spouse) {
- foreach ($spouse->getChildFamilies() as $cfamily) {
- foreach ($cfamily->getSpouses() as $parent) {
- echo FontAwesome::linkIcon('arrow-up', I18N::translate('Start at parents'), ['href' => route('descendants', ['ged' => $parent->getTree()->getName(), 'xref' => $parent->getXref(), 'generations' => $generations])]);
- // only show the arrow for one of the parents
- break;
- }
- }
- }
- echo '<br><br>&nbsp;';
- echo '</td></tr>';
+ // check if spouse has parents and add an arrow
+ echo '<td></td>';
+ echo '<td>';
+ if ($spouse) {
+ foreach ($spouse->getChildFamilies() as $cfamily) {
+ foreach ($cfamily->getSpouses() as $parent) {
+ echo FontAwesome::linkIcon('arrow-up', I18N::translate('Start at parents'), ['href' => route('descendants', ['ged' => $parent->getTree()->getName(),
+ 'xref' => $parent->getXref(),
+ 'generations' => $generations,
+ ]),
+ ]);
+ // only show the arrow for one of the parents
+ break;
+ }
+ }
+ }
+ echo '<br><br>&nbsp;';
+ echo '</td></tr>';
- // children
- $children = $family->getChildren();
- echo '<tr><td colspan="3" class="details1" >&nbsp;&nbsp;';
- if (!empty($children)) {
- echo GedcomTag::getLabel('NCHI') . ': ' . count($children);
- } else {
- // Distinguish between no children (NCHI 0) and no recorded
- // children (no CHIL records)
- if (strpos($family->getGedcom(), '\n1 NCHI 0')) {
- echo GedcomTag::getLabel('NCHI') . ': ' . count($children);
- } else {
- echo I18N::translate('No children');
- }
- }
- echo '</td></tr></table>';
- echo '</li>';
- if ($depth > 1) {
- foreach ($children as $child) {
- $this->printChildDescendancy($child, $depth - 1, $generations);
- }
- }
- echo '</ul>';
- echo '</li>';
- }
+ // children
+ $children = $family->getChildren();
+ echo '<tr><td colspan="3" class="details1" >&nbsp;&nbsp;';
+ if (!empty($children)) {
+ echo GedcomTag::getLabel('NCHI') . ': ' . count($children);
+ } else {
+ // Distinguish between no children (NCHI 0) and no recorded
+ // children (no CHIL records)
+ if (strpos($family->getGedcom(), '\n1 NCHI 0')) {
+ echo GedcomTag::getLabel('NCHI') . ': ' . count($children);
+ } else {
+ echo I18N::translate('No children');
+ }
+ }
+ echo '</td></tr></table>';
+ echo '</li>';
+ if ($depth > 1) {
+ foreach ($children as $child) {
+ $this->printChildDescendancy($child, $depth - 1, $generations);
+ }
+ }
+ echo '</ul>';
+ echo '</li>';
+ }
- /**
- * Show a tabular list of individual descendants.
- *
- * @param Tree $tree
- * @param Individual[] $descendants
- *
- * @return Response
- */
- private function descendantsIndividuals(Tree $tree, array $descendants): Response {
- $html = view('lists/individuals-table', [
- 'individuals' => $descendants,
- 'sosa' => false,
- 'tree' => $tree,
- ]);
+ /**
+ * Show a tabular list of individual descendants.
+ *
+ * @param Tree $tree
+ * @param Individual[] $descendants
+ *
+ * @return Response
+ */
+ private function descendantsIndividuals(Tree $tree, array $descendants): Response
+ {
+ $html = view('lists/individuals-table', [
+ 'individuals' => $descendants,
+ 'sosa' => false,
+ 'tree' => $tree,
+ ]);
- return new Response($html);
- }
+ return new Response($html);
+ }
- /**
- * Show a tabular list of individual descendants.
- *
- * @param Tree $tree
- * @param Individual[] $descendants
- *
- * @return Response
- */
- private function descendantsFamilies(Tree $tree, array $descendants): Response {
- $families = [];
- foreach ($descendants as $individual) {
- foreach ($individual->getChildFamilies() as $family) {
- $families[$family->getXref()] = $family;
- }
- }
+ /**
+ * Show a tabular list of individual descendants.
+ *
+ * @param Tree $tree
+ * @param Individual[] $descendants
+ *
+ * @return Response
+ */
+ private function descendantsFamilies(Tree $tree, array $descendants): Response
+ {
+ $families = [];
+ foreach ($descendants as $individual) {
+ foreach ($individual->getChildFamilies() as $family) {
+ $families[$family->getXref()] = $family;
+ }
+ }
- $html = view('lists/families-table', [
- 'families' => $families,
- 'tree' => $tree,
- ]);
+ $html = view('lists/families-table', [
+ 'families' => $families,
+ 'tree' => $tree,
+ ]);
- return new Response($html);
- }
+ return new Response($html);
+ }
- /**
- * Show a booklet view of descendants
- *
- * @TODO replace ob_start() with views.
- *
- * @param Individual $individual
- * @param int $generations
- *
- * @return Response
- */
- private function descendantsBooklet(Individual $individual, int $generations): Response {
- ob_start();
+ /**
+ * Show a booklet view of descendants
+ *
+ * @TODO replace ob_start() with views.
+ *
+ * @param Individual $individual
+ * @param int $generations
+ *
+ * @return Response
+ */
+ private function descendantsBooklet(Individual $individual, int $generations): Response
+ {
+ ob_start();
- $this->printChildFamily($individual, $generations);
+ $this->printChildFamily($individual, $generations);
- $html = ob_get_clean();
+ $html = ob_get_clean();
- return new Response($html);
- }
+ return new Response($html);
+ }
- /**
- * Print a child family
- *
- * @param Individual $person
- * @param int $depth the descendancy depth to show
- * @param string $label
- * @param string $gpid
- */
- private function printChildFamily(Individual $person, $depth, $label = '1.', $gpid = '') {
- if ($depth < 2) {
- return;
- }
- foreach ($person->getSpouseFamilies() as $family) {
- FunctionsCharts::printSosaFamily($family, '', -1, $label, $person->getXref(), $gpid, 0);
- $i = 1;
- foreach ($family->getChildren() as $child) {
- $this->printChildFamily($child, $depth - 1, $label . ($i++) . '.', $person->getXref());
- }
- }
- }
+ /**
+ * Print a child family
+ *
+ * @param Individual $person
+ * @param int $depth the descendancy depth to show
+ * @param string $label
+ * @param string $gpid
+ */
+ private function printChildFamily(Individual $person, $depth, $label = '1.', $gpid = '')
+ {
+ if ($depth < 2) {
+ return;
+ }
+ foreach ($person->getSpouseFamilies() as $family) {
+ FunctionsCharts::printSosaFamily($family, '', -1, $label, $person->getXref(), $gpid, 0);
+ $i = 1;
+ foreach ($family->getChildren() as $child) {
+ $this->printChildFamily($child, $depth - 1, $label . ($i++) . '.', $person->getXref());
+ }
+ }
+ }
- /**
- * This chart can display its output in a number of styles
- *
- * @return array
- */
- private function chartStyles(): array {
- return [
- self::CHART_STYLE_LIST => I18N::translate('List'),
- self::CHART_STYLE_BOOKLET => I18N::translate('Booklet'),
- self::CHART_STYLE_INDIVIDUALS => I18N::translate('Individuals'),
- self::CHART_STYLE_FAMILIES => I18N::translate('Families'),
- ];
- }
+ /**
+ * This chart can display its output in a number of styles
+ *
+ * @return array
+ */
+ private function chartStyles(): array
+ {
+ return [
+ self::CHART_STYLE_LIST => I18N::translate('List'),
+ self::CHART_STYLE_BOOKLET => I18N::translate('Booklet'),
+ self::CHART_STYLE_INDIVIDUALS => I18N::translate('Individuals'),
+ self::CHART_STYLE_FAMILIES => I18N::translate('Families'),
+ ];
+ }
}