1<?php 2/** 3 * webtrees: online genealogy 4 * Copyright (C) 2016 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\Functions\FunctionsPrint; 23use Fisharebest\Webtrees\GedcomRecord; 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 ->addExternalJavascript(WT_AUTOCOMPLETE_JS_URL) 83 ->addInlineJavascript('autocomplete();'); 84 85 echo '<script>'; 86 echo 'function radAncestors(elementid) {var radFamilies=document.getElementById(elementid);radFamilies.checked=true;}'; 87 echo '</script>'; 88 89 if (!$cart[$WT_TREE->getTreeId()]) { 90 echo '<h2>', I18N::translate('Family tree clippings cart'), '</h2>'; 91 } 92 93 if ($clip_ctrl->action == 'add') { 94 $record = GedcomRecord::getInstance($clip_ctrl->id, $WT_TREE); 95 if ($clip_ctrl->type === 'FAM') { ?> 96 <form action="module.php" method="get"> 97 <input type="hidden" name="mod" value="clippings"> 98 <input type="hidden" name="mod_action" value="index"> 99 <input type="hidden" name="id" value="<?php echo $clip_ctrl->id; ?>"> 100 <input type="hidden" name="type" value="<?php echo $clip_ctrl->type; ?>"> 101 <input type="hidden" name="action" value="add1"> 102 <table> 103 <thead> 104 <tr> 105 <td class="topbottombar"> 106 <?php echo I18N::translate('Add to the clippings cart'); ?> 107 </td> 108 </tr> 109 </thead> 110 <tbody> 111 <tr> 112 <td class="optionbox"> 113 <input type="radio" name="others" value="parents"> 114 <?php echo $record->getFullName(); ?> 115 </td> 116 </tr> 117 <tr> 118 <td class="optionbox"> 119 <input type="radio" name="others" value="members" checked> 120 <?php echo /* I18N: %s is a family (husband + wife) */ 121 I18N::translate('%s and their children', $record->getFullName()); ?> 122 </td> 123 </tr> 124 <tr> 125 <td class="optionbox"> 126 <input type="radio" name="others" value="descendants"> 127 <?php echo /* I18N: %s is a family (husband + wife) */ 128 I18N::translate('%s and their descendants', $record->getFullName()); ?> 129 </td> 130 </tr> 131 </tbody> 132 <tfoot> 133 <tr> 134 <td class="topbottombar"><input type="submit" value="<?php echo I18N::translate('continue'); ?>"> 135 </td> 136 </tr> 137 </tfoot> 138 </table> 139 </form> 140 <?php } elseif ($clip_ctrl->type === 'INDI') { ?> 141 <form action="module.php" method="get"> 142 <input type="hidden" name="mod" value="clippings"> 143 <input type="hidden" name="mod_action" value="index"> 144 <input type="hidden" name="id" value="<?php echo $clip_ctrl->id; ?>"> 145 <input type="hidden" name="type" value="<?php echo $clip_ctrl->type; ?>"> 146 <input type="hidden" name="action" value="add1"> 147 <table> 148 <thead> 149 <tr> 150 <td class="topbottombar"> 151 <?php echo 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 <?php echo $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 <?php echo I18N::translate('Number of generations'); ?> 212 <input type="text" size="5" name="level1" value="<?php echo $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 <?php echo I18N::translate('Number of generations'); ?> 231 <input type="text" size="5" name="level2" value="<?php echo $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 <?php echo I18N::translate('Number of generations'); ?> 250 <input type="text" size="5" name="level3" value="<?php echo $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="<?php echo I18N::translate('continue'); ?>"> 258 </td> 259 </tr> 260 </tfoot> 261 </table> 262 </form> 263 <?php } elseif ($clip_ctrl->type === 'SOUR') { ?> 264 <form action="module.php" method="get"> 265 <input type="hidden" name="mod" value="clippings"> 266 <input type="hidden" name="mod_action" value="index"> 267 <input type="hidden" name="id" value="<?php echo $clip_ctrl->id; ?>"> 268 <input type="hidden" name="type" value="<?php echo $clip_ctrl->type; ?>"> 269 <input type="hidden" name="action" value="add1"> 270 <table> 271 <thead> 272 <tr> 273 <td class="topbottombar"> 274 <?php echo I18N::translate('Add to the clippings cart'); ?> 275 </td> 276 </tr> 277 </thead> 278 <tbody> 279 <tr> 280 <td class="optionbox"> 281 <label> 282 <input type="radio" name="others" checked value="none"> 283 <?php echo $record->getFullName(); ?> 284 </label> 285 </td> 286 </tr> 287 <tr> 288 <td class="optionbox"> 289 <label> 290 <input type="radio" name="others" value="linked"> 291 <?php echo /* I18N: %s is the name of a source */ 292 I18N::translate('%s and the individuals that reference it.', $record->getFullName()); ?> 293 </label> 294 </td> 295 </tr> 296 </tbody> 297 <tfoot> 298 <tr> 299 <td class="topbottombar"> 300 <input type="submit" value="<?php echo I18N::translate('continue'); ?>"> 301 </td> 302 </tr> 303 </tfoot> 304 </table> 305 </form> 306 <?php } 307 } 308 309 if (!$cart[$WT_TREE->getTreeId()]) { 310 if ($clip_ctrl->action != 'add') { 311 echo I18N::translate('The clippings cart allows you to take extracts from this family tree and download them as a GEDCOM file.'); 312 ?> 313 <form method="get" name="addin" action="module.php"> 314 <input type="hidden" name="mod" value="clippings"> 315 <input type="hidden" name="mod_action" value="index"> 316 <table> 317 <thead> 318 <tr> 319 <td colspan="2" class="topbottombar"> 320 <?php echo I18N::translate('Add to the clippings cart'); ?> 321 </td> 322 </tr> 323 </thead> 324 <tbody> 325 <tr> 326 <td class="optionbox"> 327 <input type="hidden" name="action" value="add"> 328 <input type="text" data-autocomplete-type="IFSRO" name="id" id="cart_item_id" size="5"> 329 </td> 330 <td class="optionbox"> 331 <?php echo FunctionsPrint::printFindIndividualLink('cart_item_id'); ?> 332 <?php echo FunctionsPrint::printFindFamilyLink('cart_item_id'); ?> 333 <?php echo FunctionsPrint::printFindSourceLink('cart_item_id', ''); ?> 334 <input type="submit" value="<?php echo /* I18N: A button label. */ I18N::translate('add'); ?>"> 335 </td> 336 </tr> 337 </tbody> 338 </table> 339 </form> 340 <?php 341 } 342 343 // -- end new lines 344 echo I18N::translate('Your clippings cart is empty.'); 345 } else { 346 // Keep track of the INDI from the parent page, otherwise it will 347 // get lost after ajax updates 348 $pid = Filter::get('pid', WT_REGEX_XREF); 349 350 if ($clip_ctrl->action !== 'download' && $clip_ctrl->action !== 'add') { ?> 351 <form method="get" action="module.php"> 352 <input type="hidden" name="mod" value="clippings"> 353 <input type="hidden" name="mod_action" value="index"> 354 <input type="hidden" name="action" value="download"> 355 <input type="hidden" name="pid" value="<?php echo $pid; ?>"> 356 <table> 357 <tr> 358 <td colspan="2" class="topbottombar"> 359 <h2><?php echo I18N::translate('Download'); ?></h2> 360 </td> 361 </tr> 362 <tr> 363 <td class="descriptionbox width50 wrap"> 364 <?php echo 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.'); ?> 365 </td> 366 <td class="optionbox wrap"> 367 <input type="checkbox" name="Zip" value="yes"> 368 <?php echo I18N::translate('Zip file(s)'); ?> 369 </td> 370 </tr> 371 <tr> 372 <td class="descriptionbox width50 wrap"> 373 <?php echo I18N::translate('Include media (automatically zips files)'); ?> 374 </td> 375 <td class="optionbox"> 376 <input type="checkbox" name="IncludeMedia" value="yes"> 377 </td> 378 </tr> 379 380 <?php if (Auth::isManager($WT_TREE)) { ?> 381 <tr> 382 <td class="descriptionbox width50 wrap"> 383 <?php echo I18N::translate('Apply privacy settings'); ?> 384 </td> 385 <td class="optionbox"> 386 <input type="radio" name="privatize_export" value="none" checked> 387 <?php echo I18N::translate('None'); ?> 388 <br> 389 <input type="radio" name="privatize_export" value="gedadmin"> 390 <?php echo I18N::translate('Manager'); ?> 391 <br> 392 <input type="radio" name="privatize_export" value="user"> 393 <?php echo I18N::translate('Member'); ?> 394 <br> 395 <input type="radio" name="privatize_export" value="visitor"> 396 <?php echo I18N::translate('Visitor'); ?> 397 </td> 398 </tr> 399 <?php } elseif (Auth::isMember($WT_TREE)) { ?> 400 <tr> 401 <td class="descriptionbox width50 wrap"> 402 <?php echo I18N::translate('Apply privacy settings'); ?> 403 </td> 404 <td class="optionbox"> 405 <input type="radio" name="privatize_export" value="user" checked> <?php echo I18N::translate('Member'); ?><br> 406 <input type="radio" name="privatize_export" value="visitor"> <?php echo I18N::translate('Visitor'); ?> 407 </td> 408 </tr> 409 <?php } ?> 410 411 <tr> 412 <td class="descriptionbox width50 wrap"> 413 <?php echo I18N::translate('Convert from UTF-8 to ISO-8859-1'); ?> 414 </td> 415 <td class="optionbox"> 416 <input type="checkbox" name="convert" value="yes"> 417 </td> 418 </tr> 419 420 <tr> 421 <td class="descriptionbox width50 wrap"> 422 <?php echo I18N::translate('Add the GEDCOM media path to filenames'); ?> 423 </td> 424 <td class="optionbox"> 425 <input type="checkbox" name="conv_path" value="<?php echo Filter::escapeHtml($WT_TREE->getPreference('GEDCOM_MEDIA_PATH')); ?>"> 426 <span dir="auto"><?php echo Filter::escapeHtml($WT_TREE->getPreference('GEDCOM_MEDIA_PATH')); ?></span> 427 </td> 428 </tr> 429 430 <tr> 431 <td class="topbottombar" colspan="2"> 432 <input type="submit" value="<?php echo /* I18N: A button label. */ I18N::translate('download'); ?>"> 433 </td> 434 </tr> 435 </table> 436 </form> 437 <br> 438 439 <form method="get" name="addin" action="module.php"> 440 <input type="hidden" name="mod" value="clippings"> 441 <input type="hidden" name="mod_action" value="index"> 442 <table> 443 <thead> 444 <tr> 445 <td colspan="2" class="topbottombar" style="text-align:center; "> 446 <?php echo I18N::translate('Add to the clippings cart'); ?> 447 </td> 448 </tr> 449 </thead> 450 <tbody> 451 <tr> 452 <td class="optionbox"> 453 <input type="hidden" name="action" value="add"> 454 <input type="text" data-autocomplete-type="IFSRO" name="id" id="cart_item_id" size="8"> 455 </td> 456 <td class="optionbox"> 457 <?php echo FunctionsPrint::printFindIndividualLink('cart_item_id'); ?> 458 <?php echo FunctionsPrint::printFindFamilyLink('cart_item_id'); ?> 459 <?php echo FunctionsPrint::printFindSourceLink('cart_item_id'); ?> 460 <input type="submit" value="<?php echo /* I18N: A button label. */ I18N::translate('add'); ?>"> 461 </td> 462 </tr> 463 </tbody> 464 <tfoot> 465 <tr> 466 <th colspan="2"> 467 <a href="module.php?mod=clippings&mod_action=index&action=empty"> 468 <?php echo I18N::translate('Empty the clippings cart'); ?> 469 </a> 470 </th> 471 </tr> 472 </tfoot> 473 </table> 474 </form> 475 476 <?php } ?> 477 478 <h2> 479 <?php echo I18N::translate('Family tree clippings cart'); ?> 480 </h2> 481 <table id="mycart" class="sortable list_table width100"> 482 <thead> 483 <tr> 484 <th class="list_label"><?php echo I18N::translate('Record'); ?></th> 485 <th class="list_label"><?php echo I18N::translate('Remove'); ?></th> 486 </tr> 487 </thead> 488 <tbody> 489 <?php 490 foreach (array_keys($cart[$WT_TREE->getTreeId()]) as $xref) { 491 $record = GedcomRecord::getInstance($xref, $WT_TREE); 492 if ($record) { 493 switch ($record::RECORD_TYPE) { 494 case 'INDI': 495 $icon = 'icon-indis'; 496 break; 497 case 'FAM': 498 $icon = 'icon-sfamily'; 499 break; 500 case 'SOUR': 501 $icon = 'icon-source'; 502 break; 503 case 'REPO': 504 $icon = 'icon-repository'; 505 break; 506 case 'NOTE': 507 $icon = 'icon-note'; 508 break; 509 case 'OBJE': 510 $icon = 'icon-media'; 511 break; 512 default: 513 $icon = 'icon-clippings'; 514 break; 515 } 516 ?> 517 <tr> 518 <td class="list_value"> 519 <i class="<?php echo $icon; ?>"></i> 520 <?php 521 echo '<a href="', $record->getHtmlUrl(), '">', $record->getFullName(), '</a>'; 522 ?> 523 </td> 524 <td class="list_value center vmiddle"><a href="module.php?mod=clippings&mod_action=index&action=remove&id=<?php echo $xref; ?>" class="icon-remove" title="<?php echo I18N::translate('Remove'); ?>"></a></td> 525 </tr> 526 <?php 527 } 528 } 529 ?> 530 </table> 531 <?php 532 } 533 break; 534 default: 535 http_response_code(404); 536 break; 537 } 538 } 539 540 /** 541 * The user can re-order menus. Until they do, they are shown in this order. 542 * 543 * @return int 544 */ 545 public function defaultMenuOrder() { 546 return 20; 547 } 548 549 /** 550 * A menu, to be added to the main application menu. 551 * 552 * @return Menu|null 553 */ 554 public function getMenu() { 555 global $controller, $WT_TREE; 556 557 $submenus = []; 558 if (isset($controller->record)) { 559 $submenus[] = new Menu($this->getTitle(), 'module.php?mod=clippings&mod_action=index&ged=' . $WT_TREE->getNameUrl(), 'menu-clippingscart', ['rel' => 'nofollow']); 560 } 561 if (!empty($controller->record) && $controller->record->canShow()) { 562 $submenus[] = new Menu(I18N::translate('Add to the clippings cart'), 'module.php?mod=clippings&mod_action=index&action=add&id=' . $controller->record->getXref(), 'menu-clippingsadd', ['rel' => 'nofollow']); 563 } 564 565 if ($submenus) { 566 return new Menu($this->getTitle(), '#', 'menu-clippings', ['rel' => 'nofollow'], $submenus); 567 } else { 568 return new Menu($this->getTitle(), 'module.php?mod=clippings&mod_action=index&ged=' . $WT_TREE->getNameUrl(), 'menu-clippings', ['rel' => 'nofollow']); 569 } 570 } 571 572 /** {@inheritdoc} */ 573 public function defaultSidebarOrder() { 574 return 60; 575 } 576 577 /** {@inheritdoc} */ 578 public function hasSidebarContent() { 579 // Creating a controller has the side effect of initialising the cart 580 new ClippingsCartController; 581 582 return true; 583 } 584 585 /** 586 * Load this sidebar synchronously. 587 * 588 * @return string 589 */ 590 public function getSidebarContent() { 591 global $controller; 592 593 $controller->addInlineJavascript(' 594 jQuery("#sb_clippings_content").on("click", ".add_cart, .remove_cart", function() { 595 jQuery("#sb_clippings_content").load(this.href); 596 return false; 597 }); 598 '); 599 600 return '<div id="sb_clippings_content">' . $this->getCartList() . '</div>'; 601 } 602 603 /** {@inheritdoc} */ 604 public function getSidebarAjaxContent() { 605 global $WT_TREE; 606 607 $cart = Session::get('cart'); 608 609 $clip_ctrl = new ClippingsCartController; 610 $add = Filter::get('add', WT_REGEX_XREF); 611 $add1 = Filter::get('add1', WT_REGEX_XREF); 612 $remove = Filter::get('remove', WT_REGEX_XREF); 613 $others = Filter::get('others'); 614 $clip_ctrl->level1 = Filter::getInteger('level1'); 615 $clip_ctrl->level2 = Filter::getInteger('level2'); 616 $clip_ctrl->level3 = Filter::getInteger('level3'); 617 if ($add) { 618 $record = GedcomRecord::getInstance($add, $WT_TREE); 619 if ($record) { 620 $clip_ctrl->id = $record->getXref(); 621 $clip_ctrl->type = $record::RECORD_TYPE; 622 $clip_ctrl->addClipping($record); 623 } 624 } elseif ($add1) { 625 $record = Individual::getInstance($add1, $WT_TREE); 626 if ($record) { 627 $clip_ctrl->id = $record->getXref(); 628 $clip_ctrl->type = $record::RECORD_TYPE; 629 if ($others == 'parents') { 630 foreach ($record->getChildFamilies() as $family) { 631 $clip_ctrl->addClipping($family); 632 $clip_ctrl->addFamilyMembers($family); 633 } 634 } elseif ($others == 'ancestors') { 635 $clip_ctrl->addAncestorsToCart($record, $clip_ctrl->level1); 636 } elseif ($others == 'ancestorsfamilies') { 637 $clip_ctrl->addAncestorsToCartFamilies($record, $clip_ctrl->level2); 638 } elseif ($others == 'members') { 639 foreach ($record->getSpouseFamilies() as $family) { 640 $clip_ctrl->addClipping($family); 641 $clip_ctrl->addFamilyMembers($family); 642 } 643 } elseif ($others == 'descendants') { 644 foreach ($record->getSpouseFamilies() as $family) { 645 $clip_ctrl->addClipping($family); 646 $clip_ctrl->addFamilyDescendancy($family, $clip_ctrl->level3); 647 } 648 } 649 } 650 } elseif ($remove) { 651 unset($cart[$WT_TREE->getTreeId()][$remove]); 652 Session::put('cart', $cart); 653 } elseif (isset($_REQUEST['empty'])) { 654 $cart[$WT_TREE->getTreeId()] = []; 655 Session::put('cart', $cart); 656 } elseif (isset($_REQUEST['download'])) { 657 return $this->downloadForm($clip_ctrl); 658 } 659 660 return $this->getCartList(); 661 } 662 663 /** 664 * A list for the side bar. 665 * 666 * @return string 667 */ 668 public function getCartList() { 669 global $WT_TREE; 670 671 $cart = Session::get('cart', []); 672 if (!array_key_exists($WT_TREE->getTreeId(), $cart)) { 673 $cart[$WT_TREE->getTreeId()] = []; 674 } 675 $pid = Filter::get('pid', WT_REGEX_XREF); 676 677 if (!$cart[$WT_TREE->getTreeId()]) { 678 $out = I18N::translate('Your clippings cart is empty.'); 679 } else { 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="' . $record->getHtmlUrl() . '">'; 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 if ($cart[$WT_TREE->getTreeId()]) { 713 $out .= 714 '<br><a href="module.php?mod=' . $this->getName() . '&mod_action=ajax&empty=true&pid=' . $pid . '" class="remove_cart">' . 715 I18N::translate('Empty the clippings cart') . 716 '</a>' . 717 '<br>' . 718 '<a href="module.php?mod=' . $this->getName() . '&mod_action=ajax&download=true&pid=' . $pid . '" class="add_cart">' . 719 I18N::translate('Download') . 720 '</a>'; 721 } 722 $record = Individual::getInstance($pid, $WT_TREE); 723 if ($record && !array_key_exists($record->getXref(), $cart[$WT_TREE->getTreeId()])) { 724 $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>'; 725 } 726 727 return $out; 728 } 729 730 /** 731 * A form to choose the download options. 732 * 733 * @param ClippingsCartController $clip_ctrl 734 * 735 * @return string 736 */ 737 public function downloadForm(ClippingsCartController $clip_ctrl) { 738 global $WT_TREE; 739 740 $pid = Filter::get('pid', WT_REGEX_XREF); 741 742 $out = '<script>'; 743 $out .= 'function cancelDownload() { 744 var link = "module.php?mod=' . $this->getName() . '&mod_action=ajax&pid=' . $pid . '"; 745 jQuery("#sb_clippings_content").load(link); 746 }'; 747 $out .= '</script>'; 748 $out .= '<form method="get" action="module.php"> 749 <input type="hidden" name="mod" value="clippings"> 750 <input type="hidden" name="mod_action" value="index"> 751 <input type="hidden" name="pid" value="' . $pid . '"> 752 <input type="hidden" name="action" value="download"> 753 <table> 754 <tr><td colspan="2" class="topbottombar"><h2>' . I18N::translate('Download') . '</h2></td></tr> 755 <tr><td class="descriptionbox width50 wrap">' . I18N::translate('Zip file(s)') . '</td> 756 <td class="optionbox"><input type="checkbox" name="Zip" value="yes" checked></td></tr> 757 758 <tr><td class="descriptionbox width50 wrap">' . I18N::translate('Include media (automatically zips files)') . '</td> 759 <td class="optionbox"><input type="checkbox" name="IncludeMedia" value="yes" checked></td></tr> 760 '; 761 762 if (Auth::isManager($WT_TREE)) { 763 $out .= 764 '<tr><td class="descriptionbox width50 wrap">' . I18N::translate('Apply privacy settings') . '</td>' . 765 '<td class="optionbox">' . 766 '<input type="radio" name="privatize_export" value="none" checked> ' . I18N::translate('None') . '<br>' . 767 '<input type="radio" name="privatize_export" value="gedadmin"> ' . I18N::translate('Manager') . '<br>' . 768 '<input type="radio" name="privatize_export" value="user"> ' . I18N::translate('Member') . '<br>' . 769 '<input type="radio" name="privatize_export" value="visitor"> ' . I18N::translate('Visitor') . 770 '</td></tr>'; 771 } elseif (Auth::isMember($WT_TREE)) { 772 $out .= 773 '<tr><td class="descriptionbox width50 wrap">' . I18N::translate('Apply privacy settings') . '</td>' . 774 '<td class="list_value">' . 775 '<input type="radio" name="privatize_export" value="user" checked> ' . I18N::translate('Member') . '<br>' . 776 '<input type="radio" name="privatize_export" value="visitor"> ' . I18N::translate('Visitor') . 777 '</td></tr>'; 778 } 779 780 $out .= ' 781 <tr><td class="descriptionbox width50 wrap">' . I18N::translate('Convert from UTF-8 to ISO-8859-1') . '</td> 782 <td class="optionbox"><input type="checkbox" name="convert" value="yes"></td></tr> 783 784 <tr> 785 <td class="descriptionbox width50 wrap">' . I18N::translate('Add the GEDCOM media path to filenames') . '</td> 786 <td class="optionbox"> 787 <input type="checkbox" name="conv_path" value="' . Filter::escapeHtml($WT_TREE->getPreference('GEDCOM_MEDIA_PATH')) . '"> 788 <span dir="auto">' . Filter::escapeHtml($WT_TREE->getPreference('GEDCOM_MEDIA_PATH')) . '</span></td> 789 </tr> 790 791 <input type="hidden" name="conv_path" value="' . $clip_ctrl->conv_path . '"> 792 793 </td></tr> 794 795 <tr><td class="topbottombar" colspan="2"> 796 <input type="button" value="' . /* I18N: A button label. */ I18N::translate('cancel') . '" onclick="cancelDownload();"> 797 <input type="submit" value="' . /* I18N: A button label. */ I18N::translate('download') . '"> 798 </form>'; 799 800 return $out; 801 } 802} 803