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