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