1<?php 2/** 3 * webtrees: online genealogy 4 * Copyright (C) 2018 webtrees development team 5 * This program is free software: you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation, either version 3 of the License, or 8 * (at your option) any later version. 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * You should have received a copy of the GNU General Public License 14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 */ 16namespace Fisharebest\Webtrees\Module; 17 18use Fisharebest\Webtrees\Auth; 19use Fisharebest\Webtrees\Controller\PageController; 20use Fisharebest\Webtrees\Family; 21use Fisharebest\Webtrees\Filter; 22use Fisharebest\Webtrees\GedcomRecord; 23use Fisharebest\Webtrees\Html; 24use Fisharebest\Webtrees\I18N; 25use Fisharebest\Webtrees\Individual; 26use Fisharebest\Webtrees\Menu; 27use Fisharebest\Webtrees\Module; 28use Fisharebest\Webtrees\Module\ClippingsCart\ClippingsCartController; 29use Fisharebest\Webtrees\Session; 30 31/** 32 * Class ClippingsCartModule 33 */ 34class ClippingsCartModule extends AbstractModule implements ModuleMenuInterface, ModuleSidebarInterface { 35 /** {@inheritdoc} */ 36 public function getTitle() { 37 return /* I18N: Name of a module */ 38 I18N::translate('Clippings cart'); 39 } 40 41 /** {@inheritdoc} */ 42 public function getDescription() { 43 return /* I18N: Description of the “Clippings cart” module */ 44 I18N::translate('Select records from your family tree and save them as a GEDCOM file.'); 45 } 46 47 /** 48 * What is the default access level for this module? 49 * 50 * Some modules are aimed at admins or managers, and are not generally shown to users. 51 * 52 * @return int 53 */ 54 public function defaultAccessLevel() { 55 return Auth::PRIV_USER; 56 } 57 58 /** 59 * This is a general purpose hook, allowing modules to respond to routes 60 * of the form module.php?mod=FOO&mod_action=BAR 61 * 62 * @param string $mod_action 63 */ 64 public function modAction($mod_action) { 65 global $WT_TREE; 66 67 // Only allow access if either the menu or sidebar is enabled. 68 if ( 69 !array_key_exists($this->getName(), Module::getActiveSidebars($WT_TREE)) && 70 !array_key_exists($this->getName(), Module::getActiveMenus($WT_TREE)) 71 ) { 72 http_response_code(404); 73 74 return; 75 } 76 77 switch ($mod_action) { 78 case 'ajax': 79 $html = $this->getSidebarAjaxContent(); 80 header('Content-Type: text/html; charset=UTF-8'); 81 echo $html; 82 break; 83 case 'index': 84 global $controller, $WT_TREE; 85 86 $MAX_PEDIGREE_GENERATIONS = $WT_TREE->getPreference('MAX_PEDIGREE_GENERATIONS'); 87 88 $clip_ctrl = new ClippingsCartController; 89 $cart = Session::get('cart'); 90 91 $controller = new PageController; 92 $controller 93 ->setPageTitle($this->getTitle()) 94 ->pageHeader(); 95 96 echo '<script>'; 97 echo 'function radAncestors(elementid) {var radFamilies=document.getElementById(elementid);radFamilies.checked=true;}'; 98 echo '</script>'; 99 echo '<div class="clipping-cart">'; 100 101 if (!$cart[$WT_TREE->getTreeId()]) { 102 echo '<h2>', I18N::translate('Family tree clippings cart'), '</h2>'; 103 } 104 105 if ($clip_ctrl->action == 'add') { 106 $record = GedcomRecord::getInstance($clip_ctrl->id, $WT_TREE); 107 if ($clip_ctrl->type === 'FAM') { ?> 108 <form class="wt-page-options wt-page-options-clipping-cart hidden-print" action="module.php"> 109 <input type="hidden" name="mod" value="clippings"> 110 <input type="hidden" name="mod_action" value="index"> 111 <input type="hidden" name="id" value="<?= $clip_ctrl->id ?>"> 112 <input type="hidden" name="type" value="<?= $clip_ctrl->type ?>"> 113 <input type="hidden" name="action" value="add1"> 114 <table class="add-to center"> 115 <thead> 116 <tr> 117 <td class="topbottombar"> 118 <?= I18N::translate('Add to the clippings cart') ?> 119 </td> 120 </tr> 121 </thead> 122 <tbody> 123 <tr> 124 <td class="optionbox"> 125 <input type="radio" name="others" value="parents"> 126 <?= $record->getFullName() ?> 127 </td> 128 </tr> 129 <tr> 130 <td class="optionbox"> 131 <input type="radio" name="others" value="members" checked> 132 <?= /* I18N: %s is a family (husband + wife) */ 133 I18N::translate('%s and their children', $record->getFullName()) ?> 134 </td> 135 </tr> 136 <tr> 137 <td class="optionbox"> 138 <input type="radio" name="others" value="descendants"> 139 <?= /* I18N: %s is a family (husband + wife) */ 140 I18N::translate('%s and their descendants', $record->getFullName()) ?> 141 </td> 142 </tr> 143 </tbody> 144 <tfoot> 145 <tr> 146 <td class="topbottombar"><input type="submit" value="<?= I18N::translate('continue') ?>"> 147 </td> 148 </tr> 149 </tfoot> 150 </table> 151 </form> 152 </div> 153 <?php } elseif ($clip_ctrl->type === 'INDI') { ?> 154 <form class="wt-page-options wt-page-options-clipping-cart hidden-print" action="module.php"> 155 <input type="hidden" name="mod" value="clippings"> 156 <input type="hidden" name="mod_action" value="index"> 157 <input type="hidden" name="id" value="<?= $clip_ctrl->id ?>"> 158 <input type="hidden" name="type" value="<?= $clip_ctrl->type ?>"> 159 <input type="hidden" name="action" value="add1"> 160 <table class="add-to center"> 161 <thead> 162 <tr> 163 <td class="topbottombar"> 164 <?= I18N::translate('Add to the clippings cart') ?> 165 </td> 166 </tr> 167 </thead> 168 <tbody> 169 <tr> 170 <td class="optionbox"> 171 <label> 172 <input type="radio" name="others" checked value="none"> 173 <?= $record->getFullName() ?> 174 </label> 175 </td> 176 </tr> 177 <tr> 178 <td class="optionbox"> 179 <label> 180 <input type="radio" name="others" value="parents"> 181 <?php 182 if ($record->getSex() === 'F') { 183 echo /* I18N: %s is a woman's name */ 184 I18N::translate('%s, her parents and siblings', $record->getFullName()); 185 } else { 186 echo /* I18N: %s is a man's name */ 187 I18N::translate('%s, his parents and siblings', $record->getFullName()); 188 } 189 ?> 190 </label> 191 </td> 192 </tr> 193 <tr> 194 <td class="optionbox"> 195 <label> 196 <input type="radio" name="others" value="members"> 197 <?php 198 if ($record->getSex() === 'F') { 199 echo /* I18N: %s is a woman's name */ 200 I18N::translate('%s, her spouses and children', $record->getFullName()); 201 } else { 202 echo /* I18N: %s is a man's name */ 203 I18N::translate('%s, his spouses and children', $record->getFullName()); 204 } 205 ?> 206 </label> 207 </td> 208 </tr> 209 <tr> 210 <td class="optionbox"> 211 <label> 212 <input type="radio" name="others" value="ancestors" id="ancestors"> 213 <?php 214 if ($record->getSex() === 'F') { 215 echo /* I18N: %s is a woman's name */ 216 I18N::translate('%s and her ancestors', $record->getFullName()); 217 } else { 218 echo /* I18N: %s is a man's name */ 219 I18N::translate('%s and his ancestors', $record->getFullName()); 220 } 221 ?> 222 </label> 223 <br> 224 <?= I18N::translate('Number of generations') ?> 225 <input type="text" size="5" name="level1" value="<?= $MAX_PEDIGREE_GENERATIONS ?>" onfocus="radAncestors('ancestors');"> 226 </td> 227 </tr> 228 <tr> 229 <td class="optionbox"> 230 <label> 231 <input type="radio" name="others" value="ancestorsfamilies" id="ancestorsfamilies"> 232 <?php 233 if ($record->getSex() === 'F') { 234 echo /* I18N: %s is a woman's name */ 235 I18N::translate('%s, her ancestors and their families', $record->getFullName()); 236 } else { 237 echo /* I18N: %s is a man's name */ 238 I18N::translate('%s, his ancestors and their families', $record->getFullName()); 239 } 240 ?> 241 </label> 242 <br> 243 <?= I18N::translate('Number of generations') ?> 244 <input type="text" size="5" name="level2" value="<?= $MAX_PEDIGREE_GENERATIONS ?>" onfocus="radAncestors('ancestorsfamilies');"> 245 </td> 246 </tr> 247 <tr> 248 <td class="optionbox"> 249 <label> 250 <input type="radio" name="others" value="descendants" id="descendants"> 251 <?php 252 if ($record->getSex() === 'F') { 253 echo /* I18N: %s is a woman's name */ 254 I18N::translate('%s, her spouses and descendants', $record->getFullName()); 255 } else { 256 echo /* I18N: %s is a man's name */ 257 I18N::translate('%s, his spouses and descendants', $record->getFullName()); 258 } 259 ?> 260 </label> 261 <br> 262 <?= I18N::translate('Number of generations') ?> 263 <input type="text" size="5" name="level3" value="<?= $MAX_PEDIGREE_GENERATIONS ?>" onfocus="radAncestors('descendants');"> 264 </td> 265 </tr> 266 </tbody> 267 <tfoot> 268 <tr> 269 <td class="topbottombar"> 270 <input type="submit" value="<?= I18N::translate('continue') ?>"> 271 </td> 272 </tr> 273 </tfoot> 274 </table> 275 </form> 276 </div> 277 <?php } elseif ($clip_ctrl->type === 'SOUR') { ?> 278 <form class="wt-page-options wt-page-options-clipping-cart hidden-print" action="module.php"> 279 <input type="hidden" name="mod" value="clippings"> 280 <input type="hidden" name="mod_action" value="index"> 281 <input type="hidden" name="id" value="<?= $clip_ctrl->id ?>"> 282 <input type="hidden" name="type" value="<?= $clip_ctrl->type ?>"> 283 <input type="hidden" name="action" value="add1"> 284 <table class="add-to center"> 285 <thead> 286 <tr> 287 <td class="topbottombar"> 288 <?= I18N::translate('Add to the clippings cart') ?> 289 </td> 290 </tr> 291 </thead> 292 <tbody> 293 <tr> 294 <td class="optionbox"> 295 <label> 296 <input type="radio" name="others" checked value="none"> 297 <?= $record->getFullName() ?> 298 </label> 299 </td> 300 </tr> 301 <tr> 302 <td class="optionbox"> 303 <label> 304 <input type="radio" name="others" value="linked"> 305 <?= /* I18N: %s is the name of a source */ 306 I18N::translate('%s and the individuals that reference it.', $record->getFullName()) ?> 307 </label> 308 </td> 309 </tr> 310 </tbody> 311 <tfoot> 312 <tr> 313 <td class="topbottombar"> 314 <input type="submit" value="<?= I18N::translate('continue') ?>"> 315 </td> 316 </tr> 317 </tfoot> 318 </table> 319 </form> 320 </div> 321 <?php } 322 } 323 324 if (!$cart[$WT_TREE->getTreeId()]) { 325 if ($clip_ctrl->action != 'add') { 326 echo '<div class="center">'; 327 echo I18N::translate('The clippings cart allows you to take extracts from this family tree and download them as a GEDCOM file.'); 328 echo '</div>'; 329 ?> 330 <form class="wt-page-options wt-page-options-clipping-cart hidden-print" name="addin" action="module.php"> 331 <input type="hidden" name="mod" value="clippings"> 332 <input type="hidden" name="mod_action" value="index"> 333 <table class="add-to center"> 334 <thead> 335 <tr> 336 <td colspan="2" class="topbottombar"> 337 <?= I18N::translate('Add to the clippings cart') ?> 338 </td> 339 </tr> 340 </thead> 341 <tbody> 342 <tr> 343 <td class="optionbox"> 344 <input type="hidden" name="action" value="add"> 345 <input type="text" data-autocomplete-type="IFSRO" name="id" id="cart_item_id" size="5"> 346 </td> 347 <td class="optionbox"> 348 <input type="submit" value="<?= /* I18N: A button label. */ I18N::translate('add') ?>"> 349 </td> 350 </tr> 351 </tbody> 352 </table> 353 </form> 354 </div> 355 <?php 356 } 357 echo '<div class="center">'; 358 // -- end new lines 359 echo I18N::translate('Your clippings cart is empty.'); 360 echo '</div>'; 361 } else { 362 // Keep track of the INDI from the parent page, otherwise it will 363 // get lost after ajax updates 364 $pid = Filter::get('pid', WT_REGEX_XREF); 365 366 if ($clip_ctrl->action !== 'download' && $clip_ctrl->action !== 'add') { ?> 367 <form class="wt-page-options wt-page-options-clipping-cart hidden-print" action="module.php"> 368 <input type="hidden" name="mod" value="clippings"> 369 <input type="hidden" name="mod_action" value="index"> 370 <input type="hidden" name="action" value="download"> 371 <input type="hidden" name="pid" value="<?= $pid ?>"> 372 <table class="add-to center"> 373 <tr> 374 <td colspan="2" class="topbottombar"> 375 <h2><?= I18N::translate('Download') ?></h2> 376 </td> 377 </tr> 378 <?php if (Auth::isManager($WT_TREE)) { ?> 379 <tr> 380 <td class="descriptionbox width50 wrap"> 381 <?= I18N::translate('Apply privacy settings') ?> 382 </td> 383 <td class="optionbox"> 384 <input type="radio" name="privatize_export" value="none" checked> 385 <?= I18N::translate('None') ?> 386 <br> 387 <input type="radio" name="privatize_export" value="gedadmin"> 388 <?= I18N::translate('Manager') ?> 389 <br> 390 <input type="radio" name="privatize_export" value="user"> 391 <?= I18N::translate('Member') ?> 392 <br> 393 <input type="radio" name="privatize_export" value="visitor"> 394 <?= I18N::translate('Visitor') ?> 395 </td> 396 </tr> 397 <?php } elseif (Auth::isMember($WT_TREE)) { ?> 398 <tr> 399 <td class="descriptionbox width50 wrap"> 400 <?= I18N::translate('Apply privacy settings') ?> 401 </td> 402 <td class="optionbox"> 403 <input type="radio" name="privatize_export" value="user" checked> <?= I18N::translate('Member') ?><br> 404 <input type="radio" name="privatize_export" value="visitor"> <?= I18N::translate('Visitor') ?> 405 </td> 406 </tr> 407 <?php } ?> 408 409 <tr> 410 <td class="descriptionbox width50 wrap"> 411 <?= I18N::translate('Convert from UTF-8 to ISO-8859-1') ?> 412 </td> 413 <td class="optionbox"> 414 <input type="checkbox" name="convert" value="yes"> 415 </td> 416 </tr> 417 418 <tr> 419 <td class="topbottombar" colspan="2"> 420 <input type="submit" value="<?= /* I18N: A button label. */ I18N::translate('download') ?>"> 421 </td> 422 </tr> 423 </table> 424 </form> 425 </div> 426 <br> 427 428 <form class="wt-page-options wt-page-options-clipping-cart hidden-print" name="addin" action="module.php"> 429 <input type="hidden" name="mod" value="clippings"> 430 <input type="hidden" name="mod_action" value="index"> 431 <table class="add-to center"> 432 <thead> 433 <tr> 434 <td colspan="2" class="topbottombar" style="text-align:center; "> 435 <?= I18N::translate('Add to the clippings cart') ?> 436 </td> 437 </tr> 438 </thead> 439 <tbody> 440 <tr> 441 <td class="optionbox"> 442 <input type="hidden" name="action" value="add"> 443 <input type="text" data-autocomplete-type="IFSRO" name="id" id="cart_item_id" size="8"> 444 </td> 445 <td class="optionbox"> 446 <input type="submit" value="<?= /* I18N: A button label. */ I18N::translate('add') ?>"> 447 </td> 448 </tr> 449 </tbody> 450 <tfoot> 451 <tr> 452 <th colspan="2"> 453 <a href="module.php?mod=clippings&mod_action=index&action=empty"> 454 <?= I18N::translate('Empty the clippings cart') ?> 455 </a> 456 </th> 457 </tr> 458 </tfoot> 459 </table> 460 </form> 461 </div> 462 <?php } ?> 463 <div class="clipping-cart"> 464 <h2> 465 <?= I18N::translate('Family tree clippings cart') ?> 466 </h2> 467 <table id="mycart" class="sortable list_table width50"> 468 <thead> 469 <tr> 470 <th class="list_label"><?= I18N::translate('Record') ?></th> 471 <th class="list_label"><?= I18N::translate('Remove') ?></th> 472 </tr> 473 </thead> 474 <tbody> 475 <?php 476 foreach (array_keys($cart[$WT_TREE->getTreeId()]) as $xref) { 477 $record = GedcomRecord::getInstance($xref, $WT_TREE); 478 if ($record) { 479 switch ($record::RECORD_TYPE) { 480 case 'INDI': 481 $icon = 'icon-indis'; 482 break; 483 case 'FAM': 484 $icon = 'icon-sfamily'; 485 break; 486 case 'SOUR': 487 $icon = 'icon-source'; 488 break; 489 case 'REPO': 490 $icon = 'icon-repository'; 491 break; 492 case 'NOTE': 493 $icon = 'icon-note'; 494 break; 495 case 'OBJE': 496 $icon = 'icon-media'; 497 break; 498 default: 499 $icon = 'icon-clippings'; 500 break; 501 } 502 ?> 503 <tr> 504 <td class="list_value"> 505 <i class="<?= $icon ?>"></i> 506 <?php 507 echo '<a href="', e($record->url()), '">', $record->getFullName(), '</a>'; 508 ?> 509 </td> 510 <td class="list_value center vmiddle"><a href="module.php?mod=clippings&mod_action=index&action=remove&id=<?= $xref ?>" class="icon-remove" title="<?= I18N::translate('Remove') ?>"></a></td> 511 </tr> 512 <?php 513 } 514 } 515 ?> 516 </table> 517 </div> 518 <?php 519 } 520 break; 521 default: 522 http_response_code(404); 523 break; 524 } 525 } 526 527 /** 528 * The user can re-order menus. Until they do, they are shown in this order. 529 * 530 * @return int 531 */ 532 public function defaultMenuOrder() { 533 return 20; 534 } 535 536 /** 537 * A menu, to be added to the main application menu. 538 * 539 * @return Menu|null 540 */ 541 public function getMenu() { 542 global $controller, $WT_TREE; 543 544 $submenus = []; 545 if (isset($controller->record)) { 546 $submenus[] = new Menu($this->getTitle(), 'module.php?mod=clippings&mod_action=index&ged=' . $WT_TREE->getNameUrl(), 'menu-clippings-cart', ['rel' => 'nofollow']); 547 } 548 if (!empty($controller->record) && $controller->record->canShow()) { 549 $submenus[] = new Menu(I18N::translate('Add to the clippings cart'), 'module.php?mod=clippings&mod_action=index&action=add&id=' . $controller->record->getXref(), 'menu-clippings-add', ['rel' => 'nofollow']); 550 } 551 552 if ($submenus) { 553 return new Menu($this->getTitle(), '#', 'menu-clippings', ['rel' => 'nofollow'], $submenus); 554 } else { 555 return new Menu($this->getTitle(), 'module.php?mod=clippings&mod_action=index&ged=' . $WT_TREE->getNameUrl(), 'menu-clippings', ['rel' => 'nofollow']); 556 } 557 } 558 559 /** {@inheritdoc} */ 560 public function defaultSidebarOrder() { 561 return 60; 562 } 563 564 /** {@inheritdoc} */ 565 public function hasSidebarContent(Individual $individual) { 566 // Creating a controller has the side effect of initialising the cart 567 new ClippingsCartController; 568 569 return true; 570 } 571 572 /** 573 * Load this sidebar synchronously. 574 * 575 * @param Individual $individual 576 * 577 * @return string 578 */ 579 public function getSidebarContent(Individual $individual) { 580 global $controller; 581 582 $controller->addInlineJavascript(' 583 $("#sb_clippings_content").on("click", ".add_cart, .remove_cart", function() { 584 $("#sb_clippings_content").load(this.href); 585 return false; 586 }); 587 '); 588 589 return '<div id="sb_clippings_content">' . $this->getCartList() . '</div>'; 590 } 591 592 /** {@inheritdoc} */ 593 public function getSidebarAjaxContent() { 594 global $WT_TREE; 595 596 $cart = Session::get('cart'); 597 598 $clip_ctrl = new ClippingsCartController; 599 $add = Filter::get('add', WT_REGEX_XREF); 600 $add1 = Filter::get('add1', WT_REGEX_XREF); 601 $remove = Filter::get('remove', WT_REGEX_XREF); 602 $others = Filter::get('others'); 603 $clip_ctrl->level1 = Filter::getInteger('level1'); 604 $clip_ctrl->level2 = Filter::getInteger('level2'); 605 $clip_ctrl->level3 = Filter::getInteger('level3'); 606 if ($add) { 607 $record = GedcomRecord::getInstance($add, $WT_TREE); 608 if ($record) { 609 $clip_ctrl->id = $record->getXref(); 610 $clip_ctrl->type = $record::RECORD_TYPE; 611 $clip_ctrl->addClipping($record); 612 } 613 } elseif ($add1) { 614 $record = Individual::getInstance($add1, $WT_TREE); 615 if ($record) { 616 $clip_ctrl->id = $record->getXref(); 617 $clip_ctrl->type = $record::RECORD_TYPE; 618 if ($others == 'parents') { 619 foreach ($record->getChildFamilies() as $family) { 620 $clip_ctrl->addClipping($family); 621 $clip_ctrl->addFamilyMembers($family); 622 } 623 } elseif ($others == 'ancestors') { 624 $clip_ctrl->addAncestorsToCart($record, $clip_ctrl->level1); 625 } elseif ($others == 'ancestorsfamilies') { 626 $clip_ctrl->addAncestorsToCartFamilies($record, $clip_ctrl->level2); 627 } elseif ($others == 'members') { 628 foreach ($record->getSpouseFamilies() as $family) { 629 $clip_ctrl->addClipping($family); 630 $clip_ctrl->addFamilyMembers($family); 631 } 632 } elseif ($others == 'descendants') { 633 foreach ($record->getSpouseFamilies() as $family) { 634 $clip_ctrl->addClipping($family); 635 $clip_ctrl->addFamilyDescendancy($family, $clip_ctrl->level3); 636 } 637 } 638 } 639 } elseif ($remove) { 640 unset($cart[$WT_TREE->getTreeId()][$remove]); 641 Session::put('cart', $cart); 642 } elseif (isset($_REQUEST['empty'])) { 643 $cart[$WT_TREE->getTreeId()] = []; 644 Session::put('cart', $cart); 645 } elseif (isset($_REQUEST['download'])) { 646 return $this->downloadForm(); 647 } 648 649 return $this->getCartList(); 650 } 651 652 /** 653 * A list for the side bar. 654 * 655 * @return string 656 */ 657 public function getCartList() { 658 global $WT_TREE; 659 660 $cart = Session::get('cart', []); 661 if (!array_key_exists($WT_TREE->getTreeId(), $cart)) { 662 $cart[$WT_TREE->getTreeId()] = []; 663 } 664 $pid = Filter::get('pid', WT_REGEX_XREF); 665 666 if (!$cart[$WT_TREE->getTreeId()]) { 667 $out = I18N::translate('Your clippings cart is empty.'); 668 } else { 669 $out = ''; 670 if (!empty($cart[$WT_TREE->getTreeId()])) { 671 $out .= 672 '<a href="module.php?mod=' . $this->getName() . '&mod_action=ajax&empty=true&pid=' . $pid . '" class="remove_cart">' . 673 I18N::translate('Empty the clippings cart') . 674 '</a>' . 675 '<br>' . 676 '<a href="module.php?mod=' . $this->getName() . '&mod_action=ajax&download=true&pid=' . $pid . '" class="add_cart">' . 677 I18N::translate('Download') . 678 '</a><br><br>'; 679 } 680 $out .= '<ul>'; 681 foreach (array_keys($cart[$WT_TREE->getTreeId()]) as $xref) { 682 $record = GedcomRecord::getInstance($xref, $WT_TREE); 683 if ($record instanceof Individual || $record instanceof Family) { 684 switch ($record::RECORD_TYPE) { 685 case 'INDI': 686 $icon = 'icon-indis'; 687 break; 688 case 'FAM': 689 $icon = 'icon-sfamily'; 690 break; 691 } 692 $out .= '<li>'; 693 if (!empty($icon)) { 694 $out .= '<i class="' . $icon . '"></i>'; 695 } 696 $out .= '<a href="' . e($record->url()) . '">'; 697 if ($record instanceof Individual) { 698 $out .= $record->getSexImage(); 699 } 700 $out .= ' ' . $record->getFullName() . ' '; 701 if ($record instanceof Individual && $record->canShow()) { 702 $out .= ' (' . $record->getLifeSpan() . ')'; 703 } 704 $out .= '</a>'; 705 $out .= '<a class="icon-remove remove_cart" href="module.php?mod=' . $this->getName() . '&mod_action=ajax&remove=' . $xref . '&pid=' . $pid . '" title="' . I18N::translate('Remove') . '"></a>'; 706 $out .= '</li>'; 707 } 708 } 709 $out .= '</ul>'; 710 } 711 712 $record = Individual::getInstance($pid, $WT_TREE); 713 if ($record && !array_key_exists($record->getXref(), $cart[$WT_TREE->getTreeId()])) { 714 $out .= '<br><a href="module.php?mod=' . $this->getName() . '&mod_action=ajax&action=add1&type=INDI&id=' . $pid . '&pid=' . $pid . '" class="add_cart"><i class="icon-clippings"></i> ' . I18N::translate('Add %s to the clippings cart', $record->getFullName()) . '</a>'; 715 } 716 717 return $out; 718 } 719 720 /** 721 * A form to choose the download options. 722 * 723 * @return string 724 */ 725 public function downloadForm() { 726 global $WT_TREE; 727 728 $pid = Filter::get('pid', WT_REGEX_XREF); 729 730 $out = '<script>'; 731 $out .= 'function cancelDownload() { 732 var link = "module.php?mod=' . $this->getName() . '&mod_action=ajax&pid=' . $pid . '"; 733 $("#sb_clippings_content").load(link); 734 }'; 735 $out .= '</script>'; 736 $out .= '<form class="wt-page-options wt-page-options-clipping-cart hidden-print" action="module.php"> 737 <input type="hidden" name="mod" value="clippings"> 738 <input type="hidden" name="mod_action" value="index"> 739 <input type="hidden" name="pid" value="' . $pid . '"> 740 <input type="hidden" name="action" value="download"> 741 <table> 742 <tr><td colspan="2" class="topbottombar"><h2>' . I18N::translate('Download') . '</h2></td></tr> 743 '; 744 745 if (Auth::isManager($WT_TREE)) { 746 $out .= 747 '<tr><td class="descriptionbox width50 wrap">' . I18N::translate('Apply privacy settings') . '</td>' . 748 '<td class="optionbox">' . 749 '<input type="radio" name="privatize_export" value="none" checked> ' . I18N::translate('None') . '<br>' . 750 '<input type="radio" name="privatize_export" value="gedadmin"> ' . I18N::translate('Manager') . '<br>' . 751 '<input type="radio" name="privatize_export" value="user"> ' . I18N::translate('Member') . '<br>' . 752 '<input type="radio" name="privatize_export" value="visitor"> ' . I18N::translate('Visitor') . 753 '</td></tr>'; 754 } elseif (Auth::isMember($WT_TREE)) { 755 $out .= 756 '<tr><td class="descriptionbox width50 wrap">' . I18N::translate('Apply privacy settings') . '</td>' . 757 '<td class="list_value">' . 758 '<input type="radio" name="privatize_export" value="user" checked> ' . I18N::translate('Member') . '<br>' . 759 '<input type="radio" name="privatize_export" value="visitor"> ' . I18N::translate('Visitor') . 760 '</td></tr>'; 761 } 762 763 $out .= ' 764 <tr><td class="descriptionbox width50 wrap">' . I18N::translate('Convert from UTF-8 to ISO-8859-1') . '</td> 765 <td class="optionbox"><input type="checkbox" name="convert" value="yes"></td></tr> 766 767 <tr><td class="topbottombar" colspan="2"> 768 <input type="button" class="btn btn-secondary" value="' . /* I18N: A button label. */ I18N::translate('cancel') . '" onclick="cancelDownload();"> 769 <input type="submit" class="btn btn-primary" value="' . /* I18N: A button label. */ I18N::translate('download') . '"> 770 </form>'; 771 772 return $out; 773 } 774} 775