index.php 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435
  1. <?php
  2. require dirname(dirname(__FILE__)) . '/vendor/autoload.php';
  3. use morphos\Gender;
  4. use morphos\Russian\CardinalNumeralGenerator;
  5. use morphos\Russian\Cases;
  6. use morphos\Russian\GeographicalNamesInflection;
  7. use morphos\Russian\NounDeclension;
  8. use morphos\Russian\NounPluralization;
  9. use morphos\Russian\OrdinalNumeralGenerator;
  10. function safe_string($string)
  11. {
  12. return preg_replace('~[^А-Яа-яЁё -]~u', null, trim($string));
  13. }
  14. foreach (['name', 'noun', 'geographical-name'] as $field) {
  15. if (isset($_POST[$field])) {
  16. $_POST[$field] = safe_string($_POST[$field]);
  17. }
  18. }
  19. $gender_labels = [Gender::MALE => 'мужской', Gender::FEMALE => 'женский', Gender::NEUTER => 'средний'];
  20. ?>
  21. <!DOCTYPE html>
  22. <html lang="ru">
  23. <head>
  24. <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
  25. <link rel="stylesheet" href="https://code.getmdl.io/1.3.0/material.indigo-pink.min.css">
  26. <script defer src="https://code.getmdl.io/1.3.0/material.min.js"></script>
  27. <title>Morphos Testing Script</title>
  28. <style>
  29. .demo-layout-transparent {
  30. }
  31. .demo-layout-transparent .mdl-layout__header,
  32. .demo-layout-transparent .mdl-layout__drawer-button {
  33. /* This background is dark, so we set text to white. Use 87% black instead if
  34. your background is light. */
  35. color: white;
  36. background-color: #0B5A78;
  37. }
  38. </style>
  39. </head>
  40. <body>
  41. <div class="demo-layout-transparent mdl-layout mdl-js-layout">
  42. <header class="mdl-layout__header mdl-layout__header--transparent">
  43. <div class="mdl-layout__header-row">
  44. <!-- Title -->
  45. <span class="mdl-layout-title">Morphos Testing Script</span>
  46. <!-- Add spacer, to align navigation to the right -->
  47. <div class="mdl-layout-spacer"></div>
  48. <!-- Navigation -->
  49. <!-- <nav class="mdl-navigation">
  50. <a class="mdl-navigation__link" href="">Link</a>
  51. <a class="mdl-navigation__link" href="">Link</a>
  52. <a class="mdl-navigation__link" href="">Link</a>
  53. <a class="mdl-navigation__link" href="">Link</a>
  54. </nav> -->
  55. </div>
  56. </header>
  57. <div class="mdl-layout__drawer">
  58. <span class="mdl-layout-title">Useful links</span>
  59. <nav class="mdl-navigation">
  60. <a class="mdl-navigation__link" href="https://github.com/wapmorgan/Morphos">GitHub</a>
  61. <a class="mdl-navigation__link" href="https://packagist.org/packages/wapmorgan/morphos">Packagist</a>
  62. <a class="mdl-navigation__link" href="https://github.com/wapmorgan/Morphos-Blade">Blade adapter</a>
  63. <a class="mdl-navigation__link" href="https://github.com/wapmorgan/Morphos-Twig">Twig adapter</a>
  64. </nav>
  65. </div>
  66. <main class="mdl-layout__content">
  67. <div class="mdl-tabs mdl-js-tabs mdl-js-ripple-effect">
  68. <div class="mdl-tabs__tab-bar">
  69. <a href="#personal-names" class="mdl-tabs__tab is-active">Склонение имен собственных</a>
  70. <a href="#geographical-names" class="mdl-tabs__tab">Склонение географических названий</a>
  71. <a href="#nouns" class="mdl-tabs__tab">Склонение существительных</a>
  72. <a href="#numerals" class="mdl-tabs__tab">Генерация числительных</a>
  73. </div>
  74. <div class="mdl-tabs__panel" id="nouns">
  75. <div class="mdl-grid">
  76. <div class="mdl-cell mdl-cell--6-col" style="text-align: right;">
  77. <form method="post" action="#nouns">
  78. <table class="mdl-data-table mdl-js-data-table mdl-shadow--2dp" style="margin: 0 0 0 auto;">
  79. <tbody>
  80. <tr>
  81. <td class="mdl-data-table__cell--non-numeric">
  82. <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
  83. <input name="noun"
  84. value="<?= isset($_POST['noun']) ? htmlspecialchars($_POST['noun']) : null ?>"
  85. class="mdl-textfield__input" id="noun-input">
  86. <label class="mdl-textfield__label" for="noun-input">Существительное</label>
  87. </td>
  88. </tr>
  89. <tr>
  90. <td class="mdl-data-table__cell--non-numeric"><label><input type="checkbox"
  91. name="animate" <?= isset($_POST['animate']) ? "checked='checked'" : null ?> />
  92. Одушевлённое</label></td>
  93. </tr>
  94. <tr>
  95. <td class="mdl-data-table__cell--non-numeric"><input type="submit"
  96. value="Просклонять"/> <input
  97. name="count" type="submit" value="Посчитать до 100"/></td>
  98. </tr>
  99. </tbody>
  100. </table>
  101. </form>
  102. </div>
  103. <div class="mdl-cell mdl-cell--6-col" style="text-align: left;">
  104. <?php if (isset($_POST['noun'])): ?>
  105. <?php
  106. $animate = !empty($_POST['animate']);
  107. $noun = $_POST['noun'];
  108. ?>
  109. <?php if (!isset($_POST['count'])): ?>
  110. <?php
  111. $cases = NounDeclension::getCases($noun, $animate);
  112. ?>
  113. <table>
  114. <tr>
  115. <td>
  116. <table class="mdl-data-table mdl-js-data-table mdl-shadow--2dp">
  117. <tbody>
  118. <tr>
  119. <td class="mdl-data-table__cell--non-numeric" colspan="2"
  120. style="text-align: center;"><?= htmlspecialchars($noun) ?>
  121. (<?= NounDeclension::getDeclension($noun) ?> склонение)
  122. </td>
  123. </tr>
  124. <?php foreach ([
  125. Cases::IMENIT => 'Именительный',
  126. Cases::RODIT => 'Родительный',
  127. Cases::DAT => 'Дательный',
  128. Cases::VINIT => 'Винительный',
  129. Cases::TVORIT => 'Творительный',
  130. Cases::PREDLOJ => 'Предложный',
  131. ] as $case => $name): ?>
  132. <tr>
  133. <td class="mdl-data-table__cell--non-numeric"><?= htmlspecialchars($name) ?></td>
  134. <td class="mdl-data-table__cell--non-numeric"><?= htmlspecialchars($cases[$case]) ?></td>
  135. </tr>
  136. <?php endforeach; ?>
  137. </tbody>
  138. </table>
  139. </td>
  140. <td>
  141. <?php
  142. $cases = NounPluralization::getCases($noun, $animate);
  143. ?>
  144. <table class="mdl-data-table mdl-js-data-table mdl-shadow--2dp">
  145. <tbody>
  146. <tr>
  147. <td class="mdl-data-table__cell--non-numeric" colspan="2"
  148. style="text-align: center;"><?= htmlspecialchars($_POST['noun']) ?>
  149. (<?= htmlspecialchars(NounDeclension::getDeclension($noun)) ?> склонение) во
  150. множественном числе
  151. </td>
  152. </tr>
  153. <?php foreach ([
  154. Cases::IMENIT => 'Именительный',
  155. Cases::RODIT => 'Родительный',
  156. Cases::DAT => 'Дательный',
  157. Cases::VINIT => 'Винительный',
  158. Cases::TVORIT => 'Творительный',
  159. Cases::PREDLOJ => 'Предложный',
  160. ] as $case => $name): ?>
  161. <tr>
  162. <td class="mdl-data-table__cell--non-numeric"><?= htmlspecialchars($name) ?></td>
  163. <td class="mdl-data-table__cell--non-numeric"><?= htmlspecialchars($cases[$case]) ?></td>
  164. </tr>
  165. <?php endforeach; ?>
  166. </tbody>
  167. </table>
  168. </td>
  169. </tr>
  170. </table>
  171. <?php else: ?>
  172. <table class="mdl-data-table mdl-js-data-table mdl-shadow--2dp">
  173. <tbody>
  174. <tr>
  175. <td class="mdl-data-table__cell--non-numeric" colspan="2"
  176. style="text-align: center;"><?= htmlspecialchars($noun) ?>
  177. (<?= htmlspecialchars(NounDeclension::getDeclension($noun)) ?> склонение)
  178. </td>
  179. </tr>
  180. <?php for ($i = 1; $i <= 20; $i++): ?>
  181. <tr>
  182. <td class="mdl-data-table__cell--non-numeric">
  183. <?= $i . ' ' . htmlspecialchars(NounPluralization::pluralize($noun, $i, $animate)) ?>
  184. </td>
  185. <td class="mdl-data-table__cell--non-numeric">
  186. <?= ($i + 20) . ' ' . htmlspecialchars(NounPluralization::pluralize($noun, $i + 20, $animate)) ?>
  187. </td>
  188. <td class="mdl-data-table__cell--non-numeric">
  189. <?= ($i + 40) . ' ' . htmlspecialchars(NounPluralization::pluralize($noun, $i + 40, $animate)) ?>
  190. </td>
  191. <td class="mdl-data-table__cell--non-numeric">
  192. <?= ($i + 60) . ' ' . htmlspecialchars(NounPluralization::pluralize($noun, $i + 60, $animate)) ?>
  193. </td>
  194. <td class="mdl-data-table__cell--non-numeric">
  195. <?= ($i + 80) . ' ' . htmlspecialchars(NounPluralization::pluralize($noun, $i + 80, $animate)) ?>
  196. </td>
  197. </tr>
  198. <?php endfor; ?>
  199. </tbody>
  200. </table>
  201. <?php endif; ?>
  202. <?php endif; ?>
  203. </div>
  204. </div>
  205. </div>
  206. <div class="mdl-tabs__panel" id="geographical-names">
  207. <div class="mdl-grid">
  208. <div class="mdl-cell mdl-cell--6-col" style="text-align: right;">
  209. <form method="post" action="#geographical-names">
  210. <table class="mdl-data-table mdl-js-data-table mdl-shadow--2dp" style="margin: 0 0 0 auto;">
  211. <tbody>
  212. <tr>
  213. <td class="mdl-data-table__cell--non-numeric">
  214. <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
  215. <input name="geographical-name"
  216. value="<?= isset($_POST['geographical-name']) ? htmlspecialchars($_POST['geographical-name']) : null ?>"
  217. class="mdl-textfield__input" id="geographical-name-input">
  218. <label class="mdl-textfield__label" for="geographical-name-input">Город,
  219. страна</label>
  220. </div>
  221. </td>
  222. </tr>
  223. <tr>
  224. <td class="mdl-data-table__cell--non-numeric">
  225. <input type="submit" value="Просклонять"/>
  226. </td>
  227. </tr>
  228. </tbody>
  229. </table>
  230. </form>
  231. </div>
  232. <div class="mdl-cell mdl-cell--6-col" style="text-align: left;">
  233. <?php if (isset($_POST['geographical-name'])): ?>
  234. <?php
  235. $geographical_name = $_POST['geographical-name'];
  236. $cases = GeographicalNamesInflection::getCases($geographical_name);
  237. ?>
  238. <table class="mdl-data-table mdl-js-data-table mdl-shadow--2dp">
  239. <tbody>
  240. <tr>
  241. <td class="mdl-data-table__cell--non-numeric" colspan="2"
  242. style="text-align: center;"><?= htmlspecialchars($geographical_name) ?></td>
  243. </tr>
  244. <?php foreach ([
  245. Cases::IMENIT => 'Именительный',
  246. Cases::RODIT => 'Родительный',
  247. Cases::DAT => 'Дательный',
  248. Cases::VINIT => 'Винительный',
  249. Cases::TVORIT => 'Творительный',
  250. Cases::PREDLOJ => 'Предложный',
  251. ] as $case => $name): ?>
  252. <tr>
  253. <td class="mdl-data-table__cell--non-numeric"><?= htmlspecialchars($name) ?></td>
  254. <td class="mdl-data-table__cell--non-numeric"><?= htmlspecialchars($cases[$case]) ?></td>
  255. </tr>
  256. <?php endforeach; ?>
  257. </tbody>
  258. </table>
  259. <?php endif; ?>
  260. </div>
  261. </div>
  262. </div>
  263. <div class="mdl-tabs__panel is-active" id="personal-names">
  264. <div class="mdl-grid">
  265. <div class="mdl-cell mdl-cell--6-col" style="text-align: right;">
  266. <form method="post" action="#personal-names">
  267. <table class="mdl-data-table mdl-js-data-table mdl-shadow--2dp" style="margin: 0 0 0 auto;">
  268. <tbody>
  269. <tr>
  270. <td class="mdl-data-table__cell--non-numeric">
  271. <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
  272. <input name="name"
  273. value="<?= isset($_POST['name']) ? htmlspecialchars($_POST['name']) : null ?>"
  274. class="mdl-textfield__input" id="name-input">
  275. <label class="mdl-textfield__label" for="name-input">Фамилия Имя
  276. [Отчество]</label>
  277. </div>
  278. </td>
  279. </tr>
  280. <tr>
  281. <td class="mdl-data-table__cell--non-numeric">
  282. Выберите пол:
  283. <label><input type="radio" name="gender"
  284. value="" <?= !isset($_POST['gender']) || !in_array($_POST['gender'], [Gender::MALE, Gender::FEMALE]) ? "checked='checked'" : null ?> />
  285. Автоматически </label>
  286. <label><input type="radio" name="gender"
  287. value="<?= morphos\Gender::MALE ?>" <?= isset($_POST['gender']) && $_POST['gender'] == morphos\Gender::MALE ? "checked='checked'" : null ?> />
  288. Мужской </label>
  289. <label><input type="radio" name="gender"
  290. value="<?= morphos\Gender::FEMALE ?>" <?= isset($_POST['gender']) && $_POST['gender'] == morphos\Gender::FEMALE ? "checked='checked'" : null ?> />
  291. Женский </label>
  292. </td>
  293. </tr>
  294. <tr>
  295. <td class="mdl-data-table__cell--non-numeric">
  296. <input type="submit" value="Просклонять"/>
  297. </td>
  298. </tr>
  299. </tbody>
  300. </table>
  301. </form>
  302. </div>
  303. <div class="mdl-cell mdl-cell--6-col" style="text-align: left;">
  304. <?php if (isset($_POST['name'])): ?>
  305. <?php
  306. $name = $_POST['name'];
  307. $gender = !empty($_POST['gender']) ? $_POST['gender'] : morphos\Russian\detectGender($name);
  308. $cases = morphos\Russian\inflectName($name, null, $gender);
  309. if ($cases !== false):
  310. ?>
  311. <table class="mdl-data-table mdl-js-data-table mdl-shadow--2dp">
  312. <tbody>
  313. <tr>
  314. <td class="mdl-data-table__cell--non-numeric" colspan="2"
  315. style="text-align: center;"><?= htmlspecialchars($name) ?>
  316. (<?= isset($gender_labels[$gender]) ? htmlspecialchars($gender_labels[$gender]) : 'неопределенный' ?>
  317. пол)
  318. </td>
  319. </tr>
  320. <?php foreach ([
  321. Cases::IMENIT => 'Именительный',
  322. Cases::RODIT => 'Родительный',
  323. Cases::DAT => 'Дательный',
  324. Cases::VINIT => 'Винительный',
  325. Cases::TVORIT => 'Творительный',
  326. Cases::PREDLOJ => 'Предложный',
  327. ] as $case => $name): ?>
  328. <tr>
  329. <td class="mdl-data-table__cell--non-numeric"><?= htmlspecialchars($name) ?></td>
  330. <td class="mdl-data-table__cell--non-numeric"><?= htmlspecialchars($cases[$case]) ?></td>
  331. </tr>
  332. <?php endforeach; ?>
  333. </tbody>
  334. </table>
  335. <?php endif; ?>
  336. <?php endif; ?>
  337. </div>
  338. </div>
  339. </div>
  340. <div class="mdl-tabs__panel" id="numerals">
  341. <div class="mdl-grid">
  342. <div class="mdl-cell mdl-cell--6-col" style="text-align: right;">
  343. <form method="post" action="#numerals">
  344. <table class="mdl-data-table mdl-js-data-table mdl-shadow--2dp" style="margin: 0 0 0 auto;">
  345. <tbody>
  346. <tr>
  347. <td class="mdl-data-table__cell--non-numeric">
  348. <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
  349. <input name="number"
  350. value="<?= isset($_POST['number']) ? intval($_POST['number']) : null ?>"
  351. class="mdl-textfield__input" id="number-input">
  352. <label class="mdl-textfield__label" for="number-input">Число</label>
  353. </div>
  354. </td>
  355. </tr>
  356. <tr>
  357. <td class="mdl-data-table__cell--non-numeric">
  358. Выберите пол связанного числительного:
  359. <label><input type="radio" name="gender"
  360. value="<?= morphos\Gender::NEUTER ?>" <?= isset($_POST['gender']) && $_POST['gender'] == morphos\Gender::NEUTER ? "checked='checked'" : null ?> />
  361. Средний </label>
  362. <label><input type="radio" name="gender"
  363. value="<?= morphos\Gender::MALE ?>" <?= isset($_POST['gender']) && $_POST['gender'] == morphos\Gender::MALE ? "checked='checked'" : null ?> />
  364. Мужской </label>
  365. <label><input type="radio" name="gender"
  366. value="<?= morphos\Gender::FEMALE ?>" <?= isset($_POST['gender']) && $_POST['gender'] == morphos\Gender::FEMALE ? "checked='checked'" : null ?> />
  367. Женский </label>
  368. </td>
  369. </tr>
  370. <tr>
  371. <td class="mdl-data-table__cell--non-numeric"><input type="submit" name="ordinal"
  372. value="Сгенерировать числительные"/>
  373. </td>
  374. </tr>
  375. </tbody>
  376. </table>
  377. </form>
  378. </div>
  379. <div class="mdl-cell mdl-cell--6-col" style="text-align: left;">
  380. <?php if (isset($_POST['number'])): ?>
  381. <?php
  382. $number = intval($_POST['number']);
  383. $gender = isset($_POST['gender']) ? $_POST['gender'] : morphos\Gender::MALE;
  384. $cardinal = CardinalNumeralGenerator::getCases($number, $gender);
  385. $ordinal = OrdinalNumeralGenerator::getCases($number, $gender);
  386. ?>
  387. <table class="mdl-data-table mdl-js-data-table mdl-shadow--2dp">
  388. <thead>
  389. <tr>
  390. <th class="mdl-data-table__cell--non-numeric" style="text-align: center;"><?= $number ?>
  391. (<?= htmlspecialchars($gender_labels[$gender]) ?> род)
  392. </th>
  393. <th class="mdl-data-table__cell--non-numeric" style="text-align: center;">
  394. Количественное
  395. </th>
  396. <th class="mdl-data-table__cell--non-numeric" style="text-align: center;">Порядковое
  397. </th>
  398. </tr>
  399. </thead>
  400. <tbody>
  401. <?php foreach ([
  402. Cases::IMENIT => 'Именительный',
  403. Cases::RODIT => 'Родительный',
  404. Cases::DAT => 'Дательный',
  405. Cases::VINIT => 'Винительный',
  406. Cases::TVORIT => 'Творительный',
  407. Cases::PREDLOJ => 'Предложный',
  408. ] as $case => $name): ?>
  409. <tr>
  410. <td class="mdl-data-table__cell--non-numeric"><?= htmlspecialchars($name) ?></td>
  411. <td class="mdl-data-table__cell--non-numeric"><?= htmlspecialchars($cardinal[$case]) ?></td>
  412. <td class="mdl-data-table__cell--non-numeric"><?= htmlspecialchars($ordinal[$case]) ?></td>
  413. </tr>
  414. <?php endforeach; ?>
  415. </tbody>
  416. </table>
  417. <?php endif; ?>
  418. </div>
  419. </div>
  420. </div>
  421. </main>
  422. </div>
  423. </body>
  424. </html>