xref: /webtrees/app/Module/TopSurnamesModule.php (revision e490cd80ad2d75f9f6adf9b41698ad3f3f058276)
18c2e8227SGreg Roach<?php
28c2e8227SGreg Roach/**
38c2e8227SGreg Roach * webtrees: online genealogy
41062a142SGreg Roach * Copyright (C) 2018 webtrees development team
58c2e8227SGreg Roach * This program is free software: you can redistribute it and/or modify
68c2e8227SGreg Roach * it under the terms of the GNU General Public License as published by
78c2e8227SGreg Roach * the Free Software Foundation, either version 3 of the License, or
88c2e8227SGreg Roach * (at your option) any later version.
98c2e8227SGreg Roach * This program is distributed in the hope that it will be useful,
108c2e8227SGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of
118c2e8227SGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
128c2e8227SGreg Roach * GNU General Public License for more details.
138c2e8227SGreg Roach * You should have received a copy of the GNU General Public License
148c2e8227SGreg Roach * along with this program. If not, see <http://www.gnu.org/licenses/>.
158c2e8227SGreg Roach */
1676692c8bSGreg Roachnamespace Fisharebest\Webtrees\Module;
1776692c8bSGreg Roach
180e62c4b8SGreg Roachuse Fisharebest\Webtrees\Auth;
190e62c4b8SGreg Roachuse Fisharebest\Webtrees\Filter;
203d7a8a4cSGreg Roachuse Fisharebest\Webtrees\Functions\FunctionsDb;
213d7a8a4cSGreg Roachuse Fisharebest\Webtrees\Functions\FunctionsPrintLists;
220e62c4b8SGreg Roachuse Fisharebest\Webtrees\I18N;
230e62c4b8SGreg Roachuse Fisharebest\Webtrees\Query\QueryName;
24*e490cd80SGreg Roachuse Fisharebest\Webtrees\Tree;
258c2e8227SGreg Roach
268c2e8227SGreg Roach/**
278c2e8227SGreg Roach * Class TopSurnamesModule
288c2e8227SGreg Roach */
29e2a378d3SGreg Roachclass TopSurnamesModule extends AbstractModule implements ModuleBlockInterface {
30c385536dSGreg Roach	// Default values for new blocks.
31c385536dSGreg Roach	const DEFAULT_NUMBER = 10;
32c385536dSGreg Roach	const DEFAULT_STYLE  = 'table';
33c385536dSGreg Roach
3476692c8bSGreg Roach	/**
3576692c8bSGreg Roach	 * How should this module be labelled on tabs, menus, etc.?
3676692c8bSGreg Roach	 *
3776692c8bSGreg Roach	 * @return string
3876692c8bSGreg Roach	 */
398c2e8227SGreg Roach	public function getTitle() {
408c2e8227SGreg Roach		return /* I18N: Name of a module. Top=Most common */ I18N::translate('Top surnames');
418c2e8227SGreg Roach	}
428c2e8227SGreg Roach
4376692c8bSGreg Roach	/**
4476692c8bSGreg Roach	 * A sentence describing what this module does.
4576692c8bSGreg Roach	 *
4676692c8bSGreg Roach	 * @return string
4776692c8bSGreg Roach	 */
488c2e8227SGreg Roach	public function getDescription() {
498c2e8227SGreg Roach		return /* I18N: Description of the “Top surnames” module */ I18N::translate('A list of the most popular surnames.');
508c2e8227SGreg Roach	}
518c2e8227SGreg Roach
5276692c8bSGreg Roach	/**
5376692c8bSGreg Roach	 * Generate the HTML content of this block.
5476692c8bSGreg Roach	 *
55*e490cd80SGreg Roach	 * @param Tree     $tree
5676692c8bSGreg Roach	 * @param int      $block_id
5776692c8bSGreg Roach	 * @param bool     $template
58727f238cSGreg Roach	 * @param string[] $cfg
5976692c8bSGreg Roach	 *
6076692c8bSGreg Roach	 * @return string
6176692c8bSGreg Roach	 */
62*e490cd80SGreg Roach	public function getBlock(Tree $tree, int $block_id, bool $template = true, array $cfg = []): string {
63*e490cd80SGreg Roach		global $ctype;
648c2e8227SGreg Roach
65c385536dSGreg Roach		$num       = $this->getBlockSetting($block_id, 'num', self::DEFAULT_NUMBER);
66c385536dSGreg Roach		$infoStyle = $this->getBlockSetting($block_id, 'infoStyle', self::DEFAULT_STYLE);
678c2e8227SGreg Roach
68c385536dSGreg Roach		extract($cfg, EXTR_OVERWRITE);
698c2e8227SGreg Roach
708c2e8227SGreg Roach		// This next function is a bit out of date, and doesn't cope well with surname variants
71*e490cd80SGreg Roach		$top_surnames = FunctionsDb::getTopSurnames($tree->getTreeId(), 0, $num);
728c2e8227SGreg Roach
7313abd6f3SGreg Roach		$all_surnames = [];
748c2e8227SGreg Roach		$i            = 0;
758c2e8227SGreg Roach		foreach (array_keys($top_surnames) as $top_surname) {
76*e490cd80SGreg Roach			$all_surnames = array_merge($all_surnames, QueryName::surnames($tree, $top_surname, '', false, false));
778c2e8227SGreg Roach			if (++$i == $num) {
788c2e8227SGreg Roach				break;
798c2e8227SGreg Roach			}
808c2e8227SGreg Roach		}
818c2e8227SGreg Roach		if ($i < $num) {
828c2e8227SGreg Roach			$num = $i;
838c2e8227SGreg Roach		}
848c2e8227SGreg Roach
858c2e8227SGreg Roach		switch ($infoStyle) {
868c2e8227SGreg Roach			case 'tagcloud':
870e62c4b8SGreg Roach				uksort($all_surnames, '\Fisharebest\Webtrees\I18N::strcasecmp');
88*e490cd80SGreg Roach				$content = FunctionsPrintLists::surnameTagCloud($all_surnames, 'individual-list', true, $tree);
898c2e8227SGreg Roach				break;
908c2e8227SGreg Roach			case 'list':
910e62c4b8SGreg Roach				uasort($all_surnames, '\Fisharebest\Webtrees\Module\TopSurnamesModule::surnameCountSort');
92*e490cd80SGreg Roach				$content = FunctionsPrintLists::surnameList($all_surnames, 1, true, 'individual-list', $tree);
938c2e8227SGreg Roach				break;
948c2e8227SGreg Roach			case 'array':
950e62c4b8SGreg Roach				uasort($all_surnames, '\Fisharebest\Webtrees\Module\TopSurnamesModule::surnameCountSort');
96*e490cd80SGreg Roach				$content = FunctionsPrintLists::surnameList($all_surnames, 2, true, 'individual-list', $tree);
978c2e8227SGreg Roach				break;
988c2e8227SGreg Roach			case 'table':
998c2e8227SGreg Roach			default:
1000e62c4b8SGreg Roach				uasort($all_surnames, '\Fisharebest\Webtrees\Module\TopSurnamesModule::surnameCountSort');
101cf184a4dSGreg Roach				$content = view('lists/surnames-table', [
1026ab54c76SGreg Roach					'surnames' => $all_surnames,
1036ab54c76SGreg Roach					'route'    => 'individual-list',
104*e490cd80SGreg Roach					'tree'     => $tree,
1056ab54c76SGreg Roach				]);
1068c2e8227SGreg Roach				break;
1078c2e8227SGreg Roach		}
1088c2e8227SGreg Roach
1098c2e8227SGreg Roach		if ($template) {
1108cbbfdceSGreg Roach			if ($num == 1) {
1118cbbfdceSGreg Roach				// I18N: i.e. most popular surname.
1128cbbfdceSGreg Roach				$title = I18N::translate('Top surname');
1138cbbfdceSGreg Roach			} else {
1148cbbfdceSGreg Roach				// I18N: Title for a list of the most common surnames, %s is a number. Note that a separate translation exists when %s is 1
1158cbbfdceSGreg Roach				$title = I18N::plural('Top %s surname', 'Top %s surnames', $num, I18N::number($num));
1168cbbfdceSGreg Roach			}
1178cbbfdceSGreg Roach
118*e490cd80SGreg Roach			if ($ctype === 'gedcom' && Auth::isManager($tree)) {
119*e490cd80SGreg Roach				$config_url = route('tree-page-block-edit', ['block_id' => $block_id, 'ged' => $tree->getName()]);
120397e599aSGreg Roach			} elseif ($ctype === 'user' && Auth::check()) {
121*e490cd80SGreg Roach				$config_url = route('user-page-block-edit', ['block_id' => $block_id, 'ged' => $tree->getName()]);
1228cbbfdceSGreg Roach			} else {
1238cbbfdceSGreg Roach				$config_url = '';
1248cbbfdceSGreg Roach			}
1258cbbfdceSGreg Roach
126225e381fSGreg Roach			return view('blocks/template', [
1279c6524dcSGreg Roach				'block'      => str_replace('_', '-', $this->getName()),
1289c6524dcSGreg Roach				'id'         => $block_id,
1298cbbfdceSGreg Roach				'config_url' => $config_url,
1308cbbfdceSGreg Roach				'title'      => $title,
1319c6524dcSGreg Roach				'content'    => $content,
1329c6524dcSGreg Roach			]);
1338c2e8227SGreg Roach		} else {
1348c2e8227SGreg Roach			return $content;
1358c2e8227SGreg Roach		}
1368c2e8227SGreg Roach	}
1378c2e8227SGreg Roach
1388c2e8227SGreg Roach	/** {@inheritdoc} */
139a9430be8SGreg Roach	public function loadAjax(): bool {
1404ecf4f82SGreg Roach		return false;
1418c2e8227SGreg Roach	}
1428c2e8227SGreg Roach
1438c2e8227SGreg Roach	/** {@inheritdoc} */
144a9430be8SGreg Roach	public function isUserBlock(): bool {
1458c2e8227SGreg Roach		return true;
1468c2e8227SGreg Roach	}
1478c2e8227SGreg Roach
1488c2e8227SGreg Roach	/** {@inheritdoc} */
149a9430be8SGreg Roach	public function isGedcomBlock(): bool {
1508c2e8227SGreg Roach		return true;
1518c2e8227SGreg Roach	}
1528c2e8227SGreg Roach
15376692c8bSGreg Roach	/**
15476692c8bSGreg Roach	 * An HTML form to edit block settings
15576692c8bSGreg Roach	 *
156*e490cd80SGreg Roach	 * @param Tree $tree
15776692c8bSGreg Roach	 * @param int  $block_id
158a9430be8SGreg Roach	 *
159a9430be8SGreg Roach	 * @return void
16076692c8bSGreg Roach	 */
161*e490cd80SGreg Roach	public function configureBlock(Tree $tree, int $block_id) {
162c385536dSGreg Roach		if ($_SERVER['REQUEST_METHOD'] === 'POST') {
163e2a378d3SGreg Roach			$this->setBlockSetting($block_id, 'num', Filter::postInteger('num', 1, 10000, 10));
164c385536dSGreg Roach			$this->setBlockSetting($block_id, 'infoStyle', Filter::post('infoStyle', 'list|array|table|tagcloud', self::DEFAULT_STYLE));
165c385536dSGreg Roach
166c385536dSGreg Roach			return;
1678c2e8227SGreg Roach		}
1688c2e8227SGreg Roach
169c385536dSGreg Roach		$num       = $this->getBlockSetting($block_id, 'num', self::DEFAULT_NUMBER);
170c385536dSGreg Roach		$infoStyle = $this->getBlockSetting($block_id, 'infoStyle', self::DEFAULT_STYLE);
1718c2e8227SGreg Roach
172c385536dSGreg Roach		$info_styles = [
173c385536dSGreg Roach			'list'     => /* I18N: An option in a list-box */ I18N::translate('bullet list'),
174c385536dSGreg Roach			'array'    => /* I18N: An option in a list-box */ I18N::translate('compact list'),
175c385536dSGreg Roach			'table'    => /* I18N: An option in a list-box */ I18N::translate('table'),
176c385536dSGreg Roach			'tagcloud' => /* I18N: An option in a list-box */ I18N::translate('tag cloud'),
177c385536dSGreg Roach		];
1788c2e8227SGreg Roach
179c385536dSGreg Roach		echo view('blocks/top-surnames-config', [
180c385536dSGreg Roach			'num'         => $num,
181c385536dSGreg Roach			'infoStyle'   => $infoStyle,
182c385536dSGreg Roach			'info_styles' => $info_styles,
183c385536dSGreg Roach		]);
1848c2e8227SGreg Roach	}
1858c2e8227SGreg Roach
1868c2e8227SGreg Roach	/**
1878c2e8227SGreg Roach	 * Sort (lists of counts of similar) surname by total count.
1888c2e8227SGreg Roach	 *
189cc5ab399SGreg Roach	 * @param string[][] $a
190cc5ab399SGreg Roach	 * @param string[][] $b
1918c2e8227SGreg Roach	 *
192cbc1590aSGreg Roach	 * @return int
1938c2e8227SGreg Roach	 */
1948c2e8227SGreg Roach	private static function surnameCountSort($a, $b) {
1958c2e8227SGreg Roach		$counta = 0;
1968c2e8227SGreg Roach		foreach ($a as $x) {
1978c2e8227SGreg Roach			$counta += count($x);
1988c2e8227SGreg Roach		}
1998c2e8227SGreg Roach		$countb = 0;
2008c2e8227SGreg Roach		foreach ($b as $x) {
2018c2e8227SGreg Roach			$countb += count($x);
2028c2e8227SGreg Roach		}
2038c2e8227SGreg Roach
2048c2e8227SGreg Roach		return $countb - $counta;
2058c2e8227SGreg Roach	}
2068c2e8227SGreg Roach}
207