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