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