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