A footer, to be added at the bottom of every page.

@param Tree|null $tree

@return string
323879
public function getFooter(?Tree $tree): string
    {
        if ($tree === null) {
            return '';
        }

        $contact_user   = $this->user_service->find((int) $tree->getPreference('CONTACT_USER_ID'));
        $webmaster_user = $this->user_service->find((int) $tree->getPreference('WEBMASTER_USER_ID'));

        if ($contact_user instanceof User && $contact_user === $webmaster_user) {
            return view('modules/contact-links/footer', [
                'contact_links' => $this->contactLinkEverything($contact_user),
            ]);
        }

        if ($contact_user instanceof User && $webmaster_user instanceof User) {
            return view('modules/contact-links/footer', [
                'contact_links' => $this->contactLinkGenealogy($contact_user) . '<br>' . $this->contactLinkTechnical($webmaster_user),
            ]);
        }

        if ($contact_user instanceof User) {
            return view('modules/contact-links/footer', [
                'contact_links' => $this->contactLinkGenealogy($contact_user),
            ]);
        }

        if ($webmaster_user instanceof User) {
            return view('modules/contact-links/footer', [
                'contact_links' => $this->contactLinkTechnical($webmaster_user),
            ]);
        }

        return '';
    }
461833
public function menuChangeBlocks(Tree $tree): ?Menu
    {
        $request = app(ServerRequestInterface::class);

        if (Auth::check() && $request->get('route') === 'user-page') {
            return new Menu(I18N::translate('Customize this page'), route('user-page-edit', ['ged' => $tree->name()]), 'menu-change-blocks');
        }

        if (Auth::isManager($tree) && $request->get('route') === 'tree-page') {
            return new Menu(I18N::translate('Customize this page'), route('tree-page-edit', ['ged' => $tree->name()]), 'menu-change-blocks');
        }

        return null;
    }
802849
public function build( $tree )
	{
		$lines	= array();
		$children	= $tree->getChildren();
		foreach( $children as $child )
			foreach( self::buildRecursive( $child ) as $line )
				$lines[]	= $line;
		return implode( self::$lineBreak, $lines );
	}
398743
protected function buildJsOptions(Tree $tree)
    {
        $options = array();
        $options['collapsable'] = $tree->collapsable;
        $options['start_expanded'] = $tree->startExpanded;
        $options['ajax_relocate_url'] = $tree->relocateUrl;
        $options['ajax_relocate_type'] = $tree->relocateType;
        return $options;
    }
325507
public function getDeathPlace(): Place
    {
        foreach ($this->getAllDeathPlaces() as $place) {
            return $place;
        }

        return new Place('', $this->tree);
    }
896809
public function addFooter($items)
    {
        if (! is_array($items)) {
            $items = func_get_args();
        }

        $this->addElement(new Footer($items));

        return $this;
    }
856316
public function getMenu(Tree $tree): ?Menu
    {
        $submenu = [
            $this->calendarDayMenu($tree),
            $this->calendarMonthMenu($tree),
            $this->calendarYearMenu($tree),
        ];

        return new Menu(I18N::translate('Calendar'), '#', 'menu-calendar', ['rel' => 'nofollow'], $submenu);
    }
1311689
public function footer()
    {
        $this->SetY(- 15);
        $this->drawLine();
        $this->SetFontSize(10);
        $this->Cell(0, 10, $this->infoTextForFooter, 0, false, 'L', 0, '', 0, false, 'T', 'M');
        $textForFooterRight = __('Page_{0}_of_{1}', [$this->getAliasNumPage(), $this->getAliasNbPages()]);
        $this->Cell(0, 10, $textForFooterRight, 0, false, 'R', 0, '', 0, false, 'T', 'M');
        $this->SetFontSize(12);
    }
363562
private function wizardStepExport(Tree $tree): ResponseInterface
    {
        // We store the data in PHP temporary storage.
        $stream = fopen('php://temp', 'wb+');

        if ($stream === false) {
            throw new RuntimeException('Failed to create temporary stream');
        }

        $filename = $tree->name() . date('-Y-m-d') . '.ged';

        if ($this->filesystem->has($filename)) {
            $this->filesystem->delete($filename);
        }

        $tree->exportGedcom($stream);
        fseek($stream, 0);
        $this->filesystem->writeStream($tree->name() . date('-Y-m-d') . '.ged', $stream);
        fclose($stream);

        return response(view('components/alert-success', [
            'alert' => I18N::translate('The family tree has been exported to %s.', e($filename)),
        ]));
    }
1271892
public function render_footer_template() {
		$output = null;
		if ( ! empty( $this->footer ) ) {
			$output .= '<script type="text/html" id="' . esc_attr( $this->id() ) . '-footer-tmpl">';
			$output .= $this->footer->render();
			$output .= '</script>';
		}

		return $output;
	}
543667
public function getMenu(Tree $tree, $reference = null) {
        $tree_url = $tree ? $tree->getNameUrl() : '';
        return new Menu($this->getTitle(), 'module.php?mod=' . $this->getName() . '&mod_action=Certificate@listAll&ged=' . $tree_url, 'menu-maj-list-certificate', array('rel' => 'nofollow'));
    }
532291
public function menuMyPage(Tree $tree): Menu
    {
        return new Menu(I18N::translate('My page'), route('user-page', ['ged' => $tree->name()]), 'menu-mypage');
    }
692036
public function userPageEdit(Tree $tree, UserInterface $user): ResponseInterface
    {
        $main_blocks = $this->userBlocks($user->id(), 'main');
        $side_blocks = $this->userBlocks($user->id(), 'side');
        $all_blocks  = $this->availableUserBlocks();
        $title       = I18N::translate('Change the “My page” blocks');
        $url_cancel  = route('user-page', ['ged' => $tree->name()]);
        $url_save    = route('user-page-update', ['ged' => $tree->name()]);

        return $this->viewResponse('edit-blocks-page', [
            'all_blocks'  => $all_blocks,
            'can_reset'   => true,
            'main_blocks' => $main_blocks,
            'side_blocks' => $side_blocks,
            'title'       => $title,
            'url_cancel'  => $url_cancel,
            'url_save'    => $url_save,
        ]);
    }
658058
function _buildTree(&$tree, &$element) {
        $tree[$element->name()] = $element;
        if ($element->superclass()) {
            $rootDoc = & $this->_doclet->rootDoc();
            $superclass = & $rootDoc->classNamed($element->superclass());
            if ($superclass) {
                $this->_buildTree($tree, $superclass);
            }
        }
    }
732126
private function treeOutput(TreeBase $tree, Menu $menu = null)
    {
        $items = [];

        foreach ($tree->getChildren() as $item) {
            $element = [];

            $input = [
                '#prefix'         => '<div class="tree-item clearfix">',
                '#type'           => 'textfield',
                '#attributes'     => ['class' => ['']],
                '#value'          => $item->getTitle(),
                '#theme_wrappers' => [],
                '#suffix'         => '<span class="fa fa-times"></span></div>',
            ];

            $element['data']            = drupal_render($input);
            $element['data-item-type']  = 'node';
            $element['data-item-id']    = $item->getNodeId();
            $element['data-mlid']       = $item->getId();

            if ($item->hasChildren()) {
                $elements = $this->treeOutput($item);
                $element['data'] .= drupal_render($elements);
            }

            $items[] = $element;
        }

        $build = [
            '#theme' => 'item_list',
            '#type'  => 'ol',
            '#items' => $items,
        ];

        if ($menu) {
            $build['#attributes'] = [
                'data-menu' => $menu->getName(),
                'class'     => ['sortable'],
            ];
            $build['#title'] = $menu->getTitle();

            // If tree has no children, add an empty element to allow drop.
            if (!$tree->hasChildren()) {
                $build['#items'] = [' '];
            }
        }

        return $build;
    }
863821
private function faqsForTree(Tree $tree): Collection
    {
        return DB::table('block')
            ->join('block_setting AS bs1', 'bs1.block_id', '=', 'block.block_id')
            ->join('block_setting AS bs2', 'bs2.block_id', '=', 'block.block_id')
            ->join('block_setting AS bs3', 'bs3.block_id', '=', 'block.block_id')
            ->where('module_name', '=', $this->name())
            ->where('bs1.setting_name', '=', 'header')
            ->where('bs2.setting_name', '=', 'faqbody')
            ->where('bs3.setting_name', '=', 'languages')
            ->where(static function (Builder $query) use ($tree): void {
                $query
                    ->whereNull('gedcom_id')
                    ->orWhere('gedcom_id', '=', $tree->id());
            })
            ->orderBy('block_order')
            ->select(['block.block_id', 'block_order', 'gedcom_id', 'bs1.setting_value AS header', 'bs2.setting_value AS faqbody', 'bs3.setting_value AS languages'])
            ->get();
    }
875495
private function getDumpFileFooter()
    {
        $footer = '';
        if (!$this->dumpSettings['skip-comments']) {
            $footer .= '-- Dump completed';
            if (!$this->dumpSettings['skip-dump-date']) {
                $footer .= ' on: '.date('r');
            }
            $footer .= PHP_EOL;
        }

        return $footer;
    }