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