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