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 <tr> 358 <td class="descriptionbox width50 wrap"> 359 <?= I18N::translate('To reduce the size of the download, you can compress the data into a .ZIP file. You will need to uncompress the .ZIP file before you can use it.') ?> 360 </td> 361 <td class="optionbox wrap"> 362 <input type="checkbox" name="Zip" value="yes"> 363 <?= I18N::translate('Zip file(s)') ?> 364 </td> 365 </tr> 366 <tr> 367 <td class="descriptionbox width50 wrap"> 368 <?= I18N::translate('Include media (automatically zips files)') ?> 369 </td> 370 <td class="optionbox"> 371 <input type="checkbox" name="IncludeMedia" value="yes"> 372 </td> 373 </tr> 374 375 <?php if (Auth::isManager($WT_TREE)) { ?> 376 <tr> 377 <td class="descriptionbox width50 wrap"> 378 <?= I18N::translate('Apply privacy settings') ?> 379 </td> 380 <td class="optionbox"> 381 <input type="radio" name="privatize_export" value="none" checked> 382 <?= I18N::translate('None') ?> 383 <br> 384 <input type="radio" name="privatize_export" value="gedadmin"> 385 <?= I18N::translate('Manager') ?> 386 <br> 387 <input type="radio" name="privatize_export" value="user"> 388 <?= I18N::translate('Member') ?> 389 <br> 390 <input type="radio" name="privatize_export" value="visitor"> 391 <?= I18N::translate('Visitor') ?> 392 </td> 393 </tr> 394 <?php } elseif (Auth::isMember($WT_TREE)) { ?> 395 <tr> 396 <td class="descriptionbox width50 wrap"> 397 <?= I18N::translate('Apply privacy settings') ?> 398 </td> 399 <td class="optionbox"> 400 <input type="radio" name="privatize_export" value="user" checked> <?= I18N::translate('Member') ?><br> 401 <input type="radio" name="privatize_export" value="visitor"> <?= I18N::translate('Visitor') ?> 402 </td> 403 </tr> 404 <?php } ?> 405 406 <tr> 407 <td class="descriptionbox width50 wrap"> 408 <?= I18N::translate('Convert from UTF-8 to ISO-8859-1') ?> 409 </td> 410 <td class="optionbox"> 411 <input type="checkbox" name="convert" value="yes"> 412 </td> 413 </tr> 414 415 <tr> 416 <td class="descriptionbox width50 wrap"> 417 <?= I18N::translate('Add the GEDCOM media path to filenames') ?> 418 </td> 419 <td class="optionbox"> 420 <input type="checkbox" name="conv_path" value="<?= Html::escape($WT_TREE->getPreference('GEDCOM_MEDIA_PATH')) ?>"> 421 <span dir="auto"><?= Html::escape($WT_TREE->getPreference('GEDCOM_MEDIA_PATH')) ?></span> 422 </td> 423 </tr> 424 425 <tr> 426 <td class="topbottombar" colspan="2"> 427 <input type="submit" value="<?= /* I18N: A button label. */ I18N::translate('download') ?>"> 428 </td> 429 </tr> 430 </table> 431 </form> 432 <br> 433 434 <form name="addin" action="module.php"> 435 <input type="hidden" name="mod" value="clippings"> 436 <input type="hidden" name="mod_action" value="index"> 437 <table> 438 <thead> 439 <tr> 440 <td colspan="2" class="topbottombar" style="text-align:center; "> 441 <?= I18N::translate('Add to the clippings cart') ?> 442 </td> 443 </tr> 444 </thead> 445 <tbody> 446 <tr> 447 <td class="optionbox"> 448 <input type="hidden" name="action" value="add"> 449 <input type="text" data-autocomplete-type="IFSRO" name="id" id="cart_item_id" size="8"> 450 </td> 451 <td class="optionbox"> 452 <input type="submit" value="<?= /* I18N: A button label. */ I18N::translate('add') ?>"> 453 </td> 454 </tr> 455 </tbody> 456 <tfoot> 457 <tr> 458 <th colspan="2"> 459 <a href="module.php?mod=clippings&mod_action=index&action=empty"> 460 <?= I18N::translate('Empty the clippings cart') ?> 461 </a> 462 </th> 463 </tr> 464 </tfoot> 465 </table> 466 </form> 467 468 <?php } ?> 469 470 <h2> 471 <?= I18N::translate('Family tree clippings cart') ?> 472 </h2> 473 <table id="mycart" class="sortable list_table width100"> 474 <thead> 475 <tr> 476 <th class="list_label"><?= I18N::translate('Record') ?></th> 477 <th class="list_label"><?= I18N::translate('Remove') ?></th> 478 </tr> 479 </thead> 480 <tbody> 481 <?php 482 foreach (array_keys($cart[$WT_TREE->getTreeId()]) as $xref) { 483 $record = GedcomRecord::getInstance($xref, $WT_TREE); 484 if ($record) { 485 switch ($record::RECORD_TYPE) { 486 case 'INDI': 487 $icon = 'icon-indis'; 488 break; 489 case 'FAM': 490 $icon = 'icon-sfamily'; 491 break; 492 case 'SOUR': 493 $icon = 'icon-source'; 494 break; 495 case 'REPO': 496 $icon = 'icon-repository'; 497 break; 498 case 'NOTE': 499 $icon = 'icon-note'; 500 break; 501 case 'OBJE': 502 $icon = 'icon-media'; 503 break; 504 default: 505 $icon = 'icon-clippings'; 506 break; 507 } 508 ?> 509 <tr> 510 <td class="list_value"> 511 <i class="<?= $icon ?>"></i> 512 <?php 513 echo '<a href="', $record->getHtmlUrl(), '">', $record->getFullName(), '</a>'; 514 ?> 515 </td> 516 <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> 517 </tr> 518 <?php 519 } 520 } 521 ?> 522 </table> 523 <?php 524 } 525 break; 526 default: 527 http_response_code(404); 528 break; 529 } 530 } 531 532 /** 533 * The user can re-order menus. Until they do, they are shown in this order. 534 * 535 * @return int 536 */ 537 public function defaultMenuOrder() { 538 return 20; 539 } 540 541 /** 542 * A menu, to be added to the main application menu. 543 * 544 * @return Menu|null 545 */ 546 public function getMenu() { 547 global $controller, $WT_TREE; 548 549 $submenus = []; 550 if (isset($controller->record)) { 551 $submenus[] = new Menu($this->getTitle(), 'module.php?mod=clippings&mod_action=index&ged=' . $WT_TREE->getNameUrl(), 'menu-clippings-cart', ['rel' => 'nofollow']); 552 } 553 if (!empty($controller->record) && $controller->record->canShow()) { 554 $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']); 555 } 556 557 if ($submenus) { 558 return new Menu($this->getTitle(), '#', 'menu-clippings', ['rel' => 'nofollow'], $submenus); 559 } else { 560 return new Menu($this->getTitle(), 'module.php?mod=clippings&mod_action=index&ged=' . $WT_TREE->getNameUrl(), 'menu-clippings', ['rel' => 'nofollow']); 561 } 562 } 563 564 /** {@inheritdoc} */ 565 public function defaultSidebarOrder() { 566 return 60; 567 } 568 569 /** {@inheritdoc} */ 570 public function hasSidebarContent() { 571 // Creating a controller has the side effect of initialising the cart 572 new ClippingsCartController; 573 574 return true; 575 } 576 577 /** 578 * Load this sidebar synchronously. 579 * 580 * @return string 581 */ 582 public function getSidebarContent() { 583 global $controller; 584 585 $controller->addInlineJavascript(' 586 $("#sb_clippings_content").on("click", ".add_cart, .remove_cart", function() { 587 $("#sb_clippings_content").load(this.href); 588 return false; 589 }); 590 '); 591 592 return '<div id="sb_clippings_content">' . $this->getCartList() . '</div>'; 593 } 594 595 /** {@inheritdoc} */ 596 public function getSidebarAjaxContent() { 597 global $WT_TREE; 598 599 $cart = Session::get('cart'); 600 601 $clip_ctrl = new ClippingsCartController; 602 $add = Filter::get('add', WT_REGEX_XREF); 603 $add1 = Filter::get('add1', WT_REGEX_XREF); 604 $remove = Filter::get('remove', WT_REGEX_XREF); 605 $others = Filter::get('others'); 606 $clip_ctrl->level1 = Filter::getInteger('level1'); 607 $clip_ctrl->level2 = Filter::getInteger('level2'); 608 $clip_ctrl->level3 = Filter::getInteger('level3'); 609 if ($add) { 610 $record = GedcomRecord::getInstance($add, $WT_TREE); 611 if ($record) { 612 $clip_ctrl->id = $record->getXref(); 613 $clip_ctrl->type = $record::RECORD_TYPE; 614 $clip_ctrl->addClipping($record); 615 } 616 } elseif ($add1) { 617 $record = Individual::getInstance($add1, $WT_TREE); 618 if ($record) { 619 $clip_ctrl->id = $record->getXref(); 620 $clip_ctrl->type = $record::RECORD_TYPE; 621 if ($others == 'parents') { 622 foreach ($record->getChildFamilies() as $family) { 623 $clip_ctrl->addClipping($family); 624 $clip_ctrl->addFamilyMembers($family); 625 } 626 } elseif ($others == 'ancestors') { 627 $clip_ctrl->addAncestorsToCart($record, $clip_ctrl->level1); 628 } elseif ($others == 'ancestorsfamilies') { 629 $clip_ctrl->addAncestorsToCartFamilies($record, $clip_ctrl->level2); 630 } elseif ($others == 'members') { 631 foreach ($record->getSpouseFamilies() as $family) { 632 $clip_ctrl->addClipping($family); 633 $clip_ctrl->addFamilyMembers($family); 634 } 635 } elseif ($others == 'descendants') { 636 foreach ($record->getSpouseFamilies() as $family) { 637 $clip_ctrl->addClipping($family); 638 $clip_ctrl->addFamilyDescendancy($family, $clip_ctrl->level3); 639 } 640 } 641 } 642 } elseif ($remove) { 643 unset($cart[$WT_TREE->getTreeId()][$remove]); 644 Session::put('cart', $cart); 645 } elseif (isset($_REQUEST['empty'])) { 646 $cart[$WT_TREE->getTreeId()] = []; 647 Session::put('cart', $cart); 648 } elseif (isset($_REQUEST['download'])) { 649 return $this->downloadForm($clip_ctrl); 650 } 651 652 return $this->getCartList(); 653 } 654 655 /** 656 * A list for the side bar. 657 * 658 * @return string 659 */ 660 public function getCartList() { 661 global $WT_TREE; 662 663 $cart = Session::get('cart', []); 664 if (!array_key_exists($WT_TREE->getTreeId(), $cart)) { 665 $cart[$WT_TREE->getTreeId()] = []; 666 } 667 $pid = Filter::get('pid', WT_REGEX_XREF); 668 669 if (!$cart[$WT_TREE->getTreeId()]) { 670 $out = I18N::translate('Your clippings cart is empty.'); 671 } else { 672 $out = '<ul>'; 673 foreach (array_keys($cart[$WT_TREE->getTreeId()]) as $xref) { 674 $record = GedcomRecord::getInstance($xref, $WT_TREE); 675 if ($record instanceof Individual || $record instanceof Family) { 676 switch ($record::RECORD_TYPE) { 677 case 'INDI': 678 $icon = 'icon-indis'; 679 break; 680 case 'FAM': 681 $icon = 'icon-sfamily'; 682 break; 683 } 684 $out .= '<li>'; 685 if (!empty($icon)) { 686 $out .= '<i class="' . $icon . '"></i>'; 687 } 688 $out .= '<a href="' . $record->getHtmlUrl() . '">'; 689 if ($record instanceof Individual) { 690 $out .= $record->getSexImage(); 691 } 692 $out .= ' ' . $record->getFullName() . ' '; 693 if ($record instanceof Individual && $record->canShow()) { 694 $out .= ' (' . $record->getLifeSpan() . ')'; 695 } 696 $out .= '</a>'; 697 $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>'; 698 $out .= '</li>'; 699 } 700 } 701 $out .= '</ul>'; 702 } 703 704 if ($cart[$WT_TREE->getTreeId()]) { 705 $out .= 706 '<br><a href="module.php?mod=' . $this->getName() . '&mod_action=ajax&empty=true&pid=' . $pid . '" class="remove_cart">' . 707 I18N::translate('Empty the clippings cart') . 708 '</a>' . 709 '<br>' . 710 '<a href="module.php?mod=' . $this->getName() . '&mod_action=ajax&download=true&pid=' . $pid . '" class="add_cart">' . 711 I18N::translate('Download') . 712 '</a>'; 713 } 714 $record = Individual::getInstance($pid, $WT_TREE); 715 if ($record && !array_key_exists($record->getXref(), $cart[$WT_TREE->getTreeId()])) { 716 $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>'; 717 } 718 719 return $out; 720 } 721 722 /** 723 * A form to choose the download options. 724 * 725 * @param ClippingsCartController $clip_ctrl 726 * 727 * @return string 728 */ 729 public function downloadForm(ClippingsCartController $clip_ctrl) { 730 global $WT_TREE; 731 732 $pid = Filter::get('pid', WT_REGEX_XREF); 733 734 $out = '<script>'; 735 $out .= 'function cancelDownload() { 736 var link = "module.php?mod=' . $this->getName() . '&mod_action=ajax&pid=' . $pid . '"; 737 $("#sb_clippings_content").load(link); 738 }'; 739 $out .= '</script>'; 740 $out .= '<form action="module.php"> 741 <input type="hidden" name="mod" value="clippings"> 742 <input type="hidden" name="mod_action" value="index"> 743 <input type="hidden" name="pid" value="' . $pid . '"> 744 <input type="hidden" name="action" value="download"> 745 <table> 746 <tr><td colspan="2" class="topbottombar"><h2>' . I18N::translate('Download') . '</h2></td></tr> 747 <tr><td class="descriptionbox width50 wrap">' . I18N::translate('Zip file(s)') . '</td> 748 <td class="optionbox"><input type="checkbox" name="Zip" value="yes" checked></td></tr> 749 750 <tr><td class="descriptionbox width50 wrap">' . I18N::translate('Include media (automatically zips files)') . '</td> 751 <td class="optionbox"><input type="checkbox" name="IncludeMedia" value="yes" checked></td></tr> 752 '; 753 754 if (Auth::isManager($WT_TREE)) { 755 $out .= 756 '<tr><td class="descriptionbox width50 wrap">' . I18N::translate('Apply privacy settings') . '</td>' . 757 '<td class="optionbox">' . 758 '<input type="radio" name="privatize_export" value="none" checked> ' . I18N::translate('None') . '<br>' . 759 '<input type="radio" name="privatize_export" value="gedadmin"> ' . I18N::translate('Manager') . '<br>' . 760 '<input type="radio" name="privatize_export" value="user"> ' . I18N::translate('Member') . '<br>' . 761 '<input type="radio" name="privatize_export" value="visitor"> ' . I18N::translate('Visitor') . 762 '</td></tr>'; 763 } elseif (Auth::isMember($WT_TREE)) { 764 $out .= 765 '<tr><td class="descriptionbox width50 wrap">' . I18N::translate('Apply privacy settings') . '</td>' . 766 '<td class="list_value">' . 767 '<input type="radio" name="privatize_export" value="user" checked> ' . I18N::translate('Member') . '<br>' . 768 '<input type="radio" name="privatize_export" value="visitor"> ' . I18N::translate('Visitor') . 769 '</td></tr>'; 770 } 771 772 $out .= ' 773 <tr><td class="descriptionbox width50 wrap">' . I18N::translate('Convert from UTF-8 to ISO-8859-1') . '</td> 774 <td class="optionbox"><input type="checkbox" name="convert" value="yes"></td></tr> 775 776 <tr> 777 <td class="descriptionbox width50 wrap">' . I18N::translate('Add the GEDCOM media path to filenames') . '</td> 778 <td class="optionbox"> 779 <input type="checkbox" name="conv_path" value="' . Html::escape($WT_TREE->getPreference('GEDCOM_MEDIA_PATH')) . '"> 780 <span dir="auto">' . Html::escape($WT_TREE->getPreference('GEDCOM_MEDIA_PATH')) . '</span></td> 781 </tr> 782 783 <input type="hidden" name="conv_path" value="' . $clip_ctrl->conv_path . '"> 784 785 </td></tr> 786 787 <tr><td class="topbottombar" colspan="2"> 788 <input type="button" value="' . /* I18N: A button label. */ I18N::translate('cancel') . '" onclick="cancelDownload();"> 789 <input type="submit" value="' . /* I18N: A button label. */ I18N::translate('download') . '"> 790 </form>'; 791 792 return $out; 793 } 794} 795