コード例 #1
0
ファイル: Media.php プロジェクト: jflash/webtrees
 /**
  * Each object type may have its own special rules, and re-implement this function.
  *
  * @param int $access_level
  *
  * @return bool
  */
 protected function canShowByType($access_level)
 {
     // Hide media objects if they are attached to private records
     $linked_ids = Database::prepare("SELECT l_from FROM `##link` WHERE l_to = ? AND l_file = ?")->execute(array($this->xref, $this->tree->getTreeId()))->fetchOneColumn();
     foreach ($linked_ids as $linked_id) {
         $linked_record = GedcomRecord::getInstance($linked_id, $this->tree);
         if ($linked_record && !$linked_record->canShow($access_level)) {
             return false;
         }
     }
     // ... otherwise apply default behaviour
     return parent::canShowByType($access_level);
 }
コード例 #2
0
 /**
  * Generate the HTML content of this block.
  *
  * @param int      $block_id
  * @param bool     $template
  * @param string[] $cfg
  *
  * @return string
  */
 public function getBlock($block_id, $template = true, $cfg = array())
 {
     global $ctype, $WT_TREE;
     $num = $this->getBlockSetting($block_id, 'num', '10');
     $count_placement = $this->getBlockSetting($block_id, 'count_placement', 'before');
     $block = $this->getBlockSetting($block_id, 'block', '0');
     foreach (array('count_placement', 'num', 'block') as $name) {
         if (array_key_exists($name, $cfg)) {
             ${$name} = $cfg[$name];
         }
     }
     $id = $this->getName() . $block_id;
     $class = $this->getName() . '_block';
     if ($ctype === 'gedcom' && Auth::isManager($WT_TREE) || $ctype === 'user' && Auth::check()) {
         $title = '<a class="icon-admin" title="' . I18N::translate('Configure') . '" href="block_edit.php?block_id=' . $block_id . '&amp;ged=' . $WT_TREE->getNameHtml() . '&amp;ctype=' . $ctype . '"></a>';
     } else {
         $title = '';
     }
     $title .= $this->getTitle();
     $content = '';
     // load the lines from the file
     $top10 = Database::prepare("SELECT page_parameter, page_count" . " FROM `##hit_counter`" . " WHERE gedcom_id = :tree_id AND page_name IN ('individual.php','family.php','source.php','repo.php','note.php','mediaviewer.php')" . " ORDER BY page_count DESC LIMIT :limit")->execute(array('tree_id' => $WT_TREE->getTreeId(), 'limit' => (int) $num))->fetchAssoc();
     if ($block) {
         $content .= '<table width="90%">';
     } else {
         $content .= '<table>';
     }
     foreach ($top10 as $id => $count) {
         $record = GedcomRecord::getInstance($id, $WT_TREE);
         if ($record && $record->canShow()) {
             $content .= '<tr>';
             if ($count_placement == 'before') {
                 $content .= '<td dir="ltr" style="text-align:right">[' . $count . ']</td>';
             }
             $content .= '<td class="name2" ><a href="' . $record->getHtmlUrl() . '">' . $record->getFullName() . '</a></td>';
             if ($count_placement == 'after') {
                 $content .= '<td dir="ltr" style="text-align:right">[' . $count . ']</td>';
             }
             $content .= '</tr>';
         }
     }
     $content .= "</table>";
     if ($template) {
         if ($block) {
             $class .= ' small_inner_block';
         }
         return Theme::theme()->formatBlock($id, $title, $class, $content);
     } else {
         return $content;
     }
 }
コード例 #3
0
 /**
  * This is a general purpose hook, allowing modules to respond to routes
  * of the form module.php?mod=FOO&mod_action=BAR
  *
  * @param string $mod_action
  */
 public function modAction($mod_action)
 {
     global $WT_TREE;
     switch ($mod_action) {
         case 'menu-add-favorite':
             // Process the "add to user favorites" menu item on indi/fam/etc. pages
             $record = GedcomRecord::getInstance(Filter::post('xref', WT_REGEX_XREF), $WT_TREE);
             if (Auth::check() && $record->canShowName()) {
                 self::addFavorite(array('user_id' => Auth::id(), 'gedcom_id' => $record->getTree()->getTreeId(), 'gid' => $record->getXref(), 'type' => $record::RECORD_TYPE, 'url' => null, 'note' => null, 'title' => null));
                 FlashMessages::addMessage(I18N::translate('“%s” has been added to your favorites.', $record->getFullName()));
             }
             break;
     }
 }
コード例 #4
0
 /**
  * Startup activity
  *
  * @param GedcomRecord|null $record
  */
 public function __construct(GedcomRecord $record = null)
 {
     $this->record = $record;
     // Automatically fix broken links
     if ($this->record && $this->record->canEdit()) {
         $broken_links = 0;
         foreach ($this->record->getFacts('HUSB|WIFE|CHIL|FAMS|FAMC|REPO') as $fact) {
             if (!$fact->isPendingDeletion() && $fact->getTarget() === null) {
                 $this->record->deleteFact($fact->getFactId(), false);
                 FlashMessages::addMessage(I18N::translate('The link from “%1$s” to “%2$s” has been deleted.', $this->record->getFullName(), $fact->getValue()));
                 $broken_links = true;
             }
         }
         foreach ($this->record->getFacts('NOTE|SOUR|OBJE') as $fact) {
             // These can be links or inline. Only delete links.
             if (!$fact->isPendingDeletion() && $fact->getTarget() === null && preg_match('/^@.*@$/', $fact->getValue())) {
                 $this->record->deleteFact($fact->getFactId(), false);
                 FlashMessages::addMessage(I18N::translate('The link from “%1$s” to “%2$s” has been deleted.', $this->record->getFullName(), $fact->getValue()));
                 $broken_links = true;
             }
         }
         if ($broken_links) {
             // Reload the updated family
             $this->record = GedcomRecord::getInstance($this->record->getXref(), $this->record->getTree());
         }
     }
     parent::__construct();
     // We want robots to index this page
     $this->setMetaRobots('index,follow');
     // Set a page title
     if ($this->record) {
         if ($this->record->canShowName()) {
             // e.g. "John Doe" or "1881 Census of Wales"
             $this->setPageTitle($this->record->getFullName());
         } else {
             // e.g. "Individual" or "Source"
             $record = $this->record;
             $this->setPageTitle(GedcomTag::getLabel($record::RECORD_TYPE));
         }
     } else {
         // No such record
         $this->setPageTitle(I18N::translate('Private'));
     }
 }
コード例 #5
0
    /**
     * Search for a media object.
     */
    private static function mediaQuery()
    {
        global $WT_TREE;
        $iid2 = Filter::get('iid', WT_REGEX_XREF);
        $controller = new SimpleController();
        $controller->setPageTitle(I18N::translate('Link to an existing media object'))->pageHeader();
        $record = GedcomRecord::getInstance($iid2, $WT_TREE);
        if ($record) {
            $headjs = '';
            if ($record instanceof Family) {
                if ($record->getHusband()) {
                    $headjs = $record->getHusband()->getXref();
                } elseif ($record->getWife()) {
                    $headjs = $record->getWife()->getXref();
                }
            }
            ?>
			<script>
				function insertId() {
					if (window.opener.document.getElementById('addlinkQueue')) {
						// alert('Please move this alert window and examine the contents of the pop-up window, then click OK')
						window.opener.insertRowToTable('<?php 
            echo $record->getXref();
            ?>
', '<?php 
            echo htmlspecialchars($record->getFullName());
            ?>
', '<?php 
            echo $headjs;
            ?>
');
						window.close();
					}
				}
			</script>
			<?php 
        } else {
            ?>
			<script>
				function insertId() {
					window.opener.alert('<?php 
            echo $iid2;
            ?>
 - <?php 
            echo I18N::translate('Not a valid individual, family, or source ID');
            ?>
');
					window.close();
				}
			</script>
			<?php 
        }
        ?>
		<script>window.onLoad = insertId();</script>
		<?php 
    }
コード例 #6
0
ファイル: Fact.php プロジェクト: tunandras/webtrees
 /**
  * Get the record to which this fact links
  *
  * @return Individual|Family|Source|Repository|Media|Note|null
  */
 public function getTarget()
 {
     $xref = trim($this->getValue(), '@');
     switch ($this->tag) {
         case 'FAMC':
         case 'FAMS':
             return Family::getInstance($xref, $this->getParent()->getTree());
         case 'HUSB':
         case 'WIFE':
         case 'CHIL':
             return Individual::getInstance($xref, $this->getParent()->getTree());
         case 'SOUR':
             return Source::getInstance($xref, $this->getParent()->getTree());
         case 'OBJE':
             return Media::getInstance($xref, $this->getParent()->getTree());
         case 'REPO':
             return Repository::getInstance($xref, $this->getParent()->getTree());
         case 'NOTE':
             return Note::getInstance($xref, $this->getParent()->getTree());
         default:
             return GedcomRecord::getInstance($xref, $this->getParent()->getTree());
     }
 }
コード例 #7
0
ファイル: Tree.php プロジェクト: AlexSnet/webtrees
 /**
  * Create a new record from GEDCOM data.
  *
  * @param string $gedcom
  *
  * @throws \Exception
  *
  * @return GedcomRecord
  */
 public function createRecord($gedcom)
 {
     if (preg_match('/^0 @(' . WT_REGEX_XREF . ')@ (' . WT_REGEX_TAG . ')/', $gedcom, $match)) {
         $xref = $match[1];
         $type = $match[2];
     } else {
         throw new \Exception('Invalid argument to GedcomRecord::createRecord(' . $gedcom . ')');
     }
     if (strpos("\r", $gedcom) !== false) {
         // MSDOS line endings will break things in horrible ways
         throw new \Exception('Evil line endings found in GedcomRecord::createRecord(' . $gedcom . ')');
     }
     // webtrees creates XREFs containing digits.  Anything else (e.g. “new”) is just a placeholder.
     if (!preg_match('/\\d/', $xref)) {
         $xref = $this->getNewXref($type);
         $gedcom = preg_replace('/^0 @(' . WT_REGEX_XREF . ')@/', '0 @' . $xref . '@', $gedcom);
     }
     // Create a change record, if not already present
     if (!preg_match('/\\n1 CHAN/', $gedcom)) {
         $gedcom .= "\n1 CHAN\n2 DATE " . date('d M Y') . "\n3 TIME " . date('H:i:s') . "\n2 _WT_USER " . Auth::user()->getUserName();
     }
     // Create a pending change
     Database::prepare("INSERT INTO `##change` (gedcom_id, xref, old_gedcom, new_gedcom, user_id) VALUES (?, ?, '', ?, ?)")->execute(array($this->tree_id, $xref, $gedcom, Auth::id()));
     Log::addEditLog('Create: ' . $type . ' ' . $xref);
     // Accept this pending change
     if (Auth::user()->getPreference('auto_accept')) {
         FunctionsImport::acceptAllChanges($xref, $this->tree_id);
     }
     // Return the newly created record.  Note that since GedcomRecord
     // has a cache of pending changes, we cannot use it to create a
     // record with a newly created pending change.
     return GedcomRecord::getInstance($xref, $this, $gedcom);
 }
コード例 #8
0
    /**
     * Print a table of events
     *
     * @param string[] $change_ids
     * @param string $sort
     *
     * @return string
     */
    public static function changesTable($change_ids, $sort)
    {
        global $controller, $WT_TREE;
        $n = 0;
        $table_id = 'table-chan-' . Uuid::uuid4();
        // lists requires a unique ID in case there are multiple lists per page
        switch ($sort) {
            case 'name':
                //name
                $aaSorting = "[5,'asc'], [4,'desc']";
                break;
            case 'date_asc':
                //date ascending
                $aaSorting = "[4,'asc'], [5,'asc']";
                break;
            case 'date_desc':
                //date descending
                $aaSorting = "[4,'desc'], [5,'asc']";
                break;
        }
        $html = '';
        $controller->addExternalJavascript(WT_JQUERY_DATATABLES_JS_URL)->addInlineJavascript('
				jQuery.fn.dataTableExt.oSort["unicode-asc" ]=function(a,b) {return a.replace(/<[^<]*>/, "").localeCompare(b.replace(/<[^<]*>/, ""))};
				jQuery.fn.dataTableExt.oSort["unicode-desc"]=function(a,b) {return b.replace(/<[^<]*>/, "").localeCompare(a.replace(/<[^<]*>/, ""))};
				jQuery("#' . $table_id . '").dataTable({
					dom: \'t\',
					paging: false,
					autoWidth:false,
					lengthChange: false,
					filter: false,
					' . I18N::datatablesI18N() . ',
					jQueryUI: true,
					sorting: [' . $aaSorting . '],
					columns: [
						/* 0-Type */    { sortable: false, class: "center" },
						/* 1-Record */  { dataSort: 5 },
						/* 2-Change */  { dataSort: 4 },
						/* 3-By */      null,
						/* 4-DATE */    { visible: false },
						/* 5-SORTNAME */{ type: "unicode", visible: false }
					]
				});
			');
        //-- table header
        $html .= '<table id="' . $table_id . '" class="width100">';
        $html .= '<thead><tr>';
        $html .= '<th></th>';
        $html .= '<th>' . I18N::translate('Record') . '</th>';
        $html .= '<th>' . GedcomTag::getLabel('CHAN') . '</th>';
        $html .= '<th>' . GedcomTag::getLabel('_WT_USER') . '</th>';
        $html .= '<th>DATE</th>';
        //hidden by datatables code
        $html .= '<th>SORTNAME</th>';
        //hidden by datatables code
        $html .= '</tr></thead><tbody>';
        //-- table body
        foreach ($change_ids as $change_id) {
            $record = GedcomRecord::getInstance($change_id, $WT_TREE);
            if (!$record || !$record->canShow()) {
                continue;
            }
            $html .= '<tr><td>';
            switch ($record::RECORD_TYPE) {
                case 'INDI':
                    $icon = $record->getSexImage('small');
                    break;
                case 'FAM':
                    $icon = '<i class="icon-button_family"></i>';
                    break;
                case 'OBJE':
                    $icon = '<i class="icon-button_media"></i>';
                    break;
                case 'NOTE':
                    $icon = '<i class="icon-button_note"></i>';
                    break;
                case 'SOUR':
                    $icon = '<i class="icon-button_source"></i>';
                    break;
                case 'REPO':
                    $icon = '<i class="icon-button_repository"></i>';
                    break;
                default:
                    $icon = '&nbsp;';
                    break;
            }
            $html .= '<a href="' . $record->getHtmlUrl() . '">' . $icon . '</a>';
            $html .= '</td>';
            ++$n;
            //-- Record name(s)
            $name = $record->getFullName();
            $html .= '<td class="wrap">';
            $html .= '<a href="' . $record->getHtmlUrl() . '">' . $name . '</a>';
            if ($record instanceof Individual) {
                $addname = $record->getAddName();
                if ($addname) {
                    $html .= '<div class="indent"><a href="' . $record->getHtmlUrl() . '">' . $addname . '</a></div>';
                }
            }
            $html .= "</td>";
            //-- Last change date/time
            $html .= '<td class="wrap">' . $record->lastChangeTimestamp() . '</td>';
            //-- Last change user
            $html .= '<td class="wrap">' . Filter::escapeHtml($record->lastChangeUser()) . '</td>';
            //-- change date (sortable) hidden by datatables code
            $html .= '<td>' . $record->lastChangeTimestamp(true) . '</td>';
            //-- names (sortable) hidden by datatables code
            $html .= '<td>' . $record->getSortName() . '</td></tr>';
        }
        $html .= '</tbody></table>';
        return $html;
    }
コード例 #9
0
 /**
  * A list for the side bar.
  *
  * @return string
  */
 public function getCartList()
 {
     global $WT_TREE;
     $cart = Session::get('cart', array());
     if (!array_key_exists($WT_TREE->getTreeId(), $cart)) {
         $cart[$WT_TREE->getTreeId()] = array();
     }
     $pid = Filter::get('pid', WT_REGEX_XREF);
     if (!$cart[$WT_TREE->getTreeId()]) {
         $out = I18N::translate('Your clippings cart is empty.');
     } else {
         $out = '<ul>';
         foreach (array_keys($cart[$WT_TREE->getTreeId()]) as $xref) {
             $record = GedcomRecord::getInstance($xref, $WT_TREE);
             if ($record instanceof Individual || $record instanceof Family) {
                 switch ($record::RECORD_TYPE) {
                     case 'INDI':
                         $icon = 'icon-indis';
                         break;
                     case 'FAM':
                         $icon = 'icon-sfamily';
                         break;
                 }
                 $out .= '<li>';
                 if (!empty($icon)) {
                     $out .= '<i class="' . $icon . '"></i>';
                 }
                 $out .= '<a href="' . $record->getHtmlUrl() . '">';
                 if ($record instanceof Individual) {
                     $out .= $record->getSexImage();
                 }
                 $out .= ' ' . $record->getFullName() . ' ';
                 if ($record instanceof Individual && $record->canShow()) {
                     $out .= ' (' . $record->getLifeSpan() . ')';
                 }
                 $out .= '</a>';
                 $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>';
                 $out .= '</li>';
             }
         }
         $out .= '</ul>';
     }
     if ($cart[$WT_TREE->getTreeId()]) {
         $out .= '<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">' . I18N::translate('Empty the clippings cart') . '</a>' . '<br>' . '<a href="module.php?mod=' . $this->getName() . '&amp;mod_action=ajax&amp;sb_action=clippings&amp;download=true&amp;pid=' . $pid . '" class="add_cart">' . I18N::translate('Download') . '</a>';
     }
     $record = Individual::getInstance($pid, $WT_TREE);
     if ($record && !array_key_exists($record->getXref(), $cart[$WT_TREE->getTreeId()])) {
         $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>';
     }
     return $out;
 }
コード例 #10
0
ファイル: gedrecord.php プロジェクト: AlexSnet/webtrees
 */
namespace Fisharebest\Webtrees;

/**
 * Defined in session.php
 *
 * @global Tree $WT_TREE
 */
global $WT_TREE;
use Fisharebest\Webtrees\Controller\GedcomRecordController;
use Fisharebest\Webtrees\Functions\FunctionsPrint;
use Fisharebest\Webtrees\Functions\FunctionsPrintFacts;
use Fisharebest\Webtrees\Functions\FunctionsPrintLists;
define('WT_SCRIPT_NAME', 'gedrecord.php');
require './includes/session.php';
$record = GedcomRecord::getInstance(Filter::get('pid', WT_REGEX_XREF), $WT_TREE);
if ($record instanceof Individual || $record instanceof Family || $record instanceof Source || $record instanceof Repository || $record instanceof Note || $record instanceof Media) {
    header('Location: ' . WT_BASE_URL . $record->getRawUrl());
    return;
}
$controller = new GedcomRecordController($record);
if ($controller->record && $controller->record->canShow()) {
    $controller->pageHeader();
    if ($controller->record->isPendingDeletion()) {
        if (Auth::isModerator($controller->record->getTree())) {
            echo '<p class="ui-state-highlight">', I18N::translate('This record has been deleted.  You should review the deletion and then %1$s or %2$s it.', '<a href="#" onclick="accept_changes(\'' . $controller->record->getXref() . '\');">' . I18N::translateContext('You should review the deletion and then accept or reject it.', 'accept') . '</a>', '<a href="#" onclick="reject_changes(\'' . $controller->record->getXref() . '\');">' . I18N::translateContext('You should review the deletion and then accept or reject it.', 'reject') . '</a>'), ' ', FunctionsPrint::helpLink('pending_changes'), '</p>';
        } elseif (Auth::isEditor($controller->record->getTree())) {
            echo '<p class="ui-state-highlight">', I18N::translate('This record has been deleted.  The deletion will need to be reviewed by a moderator.'), ' ', FunctionsPrint::helpLink('pending_changes'), '</p>';
        }
    } elseif ($controller->record->isPendingAddtion()) {
        if (Auth::isModerator($controller->record->getTree())) {
コード例 #11
0
ファイル: calendar.php プロジェクト: josefpavlik/webtrees
/**
 * Format a list of facts for display
 *
 * @param Fact[] $list
 * @param string $tag1
 * @param string $tag2
 * @param bool   $show_sex_symbols
 *
 * @return string
 */
function calendar_list_text($list, $tag1, $tag2, $show_sex_symbols)
{
    global $males, $females, $WT_TREE;
    $html = '';
    foreach ($list as $id => $facts) {
        $tmp = GedcomRecord::getInstance($id, $WT_TREE);
        $html .= $tag1 . '<a href="' . $tmp->getHtmlUrl() . '">' . $tmp->getFullName() . '</a> ';
        if ($show_sex_symbols && $tmp instanceof Individual) {
            switch ($tmp->getSex()) {
                case 'M':
                    $html .= '<i class="icon-sex_m_9x9" title="' . I18N::translate('Male') . '"></i>';
                    ++$males;
                    break;
                case 'F':
                    $html .= '<i class="icon-sex_f_9x9" title="' . I18N::translate('Female') . '"></i>';
                    ++$females;
                    break;
                default:
                    $html .= '<i class="icon-sex_u_9x9" title="' . I18N::translateContext('unknown gender', 'Unknown') . '"></i>';
                    break;
            }
        }
        $html .= '<div class="indent">' . $facts . '</div>' . $tag2;
    }
    return $html;
}
コード例 #12
0
 /**
  * Determine if the family parents are married.
  * 
  * Don't use the default function because we want to privatize the record but display the name
  * and the parents of the spouse if the spouse him/herself is not private.
  * 
  * @param type $family
  * @return boolean
  */
 private function getMarriage($family)
 {
     $record = GedcomRecord::getInstance($family->getXref(), $this->tree);
     foreach ($record->getFacts('MARR', false, Auth::PRIV_HIDE) as $fact) {
         if ($fact) {
             return true;
         }
     }
 }
コード例 #13
0
    /**
     * Generate the HTML content of this block.
     *
     * @param int      $block_id
     * @param bool     $template
     * @param string[] $cfg
     *
     * @return string
     */
    public function getBlock($block_id, $template = true, $cfg = array())
    {
        global $ctype, $controller, $WT_TREE;
        $show_other = $this->getBlockSetting($block_id, 'show_other', self::DEFAULT_SHOW_OTHER);
        $show_unassigned = $this->getBlockSetting($block_id, 'show_unassigned', self::DEFAULT_SHOW_UNASSIGNED);
        $show_future = $this->getBlockSetting($block_id, 'show_future', self::DEFAULT_SHOW_FUTURE);
        $block = $this->getBlockSetting($block_id, 'block', self::DEFAULT_BLOCK);
        foreach (array('show_unassigned', 'show_other', 'show_future', 'block') as $name) {
            if (array_key_exists($name, $cfg)) {
                ${$name} = $cfg[$name];
            }
        }
        $id = $this->getName() . $block_id;
        $class = $this->getName() . '_block';
        if ($ctype === 'gedcom' && Auth::isManager($WT_TREE) || $ctype === 'user' && Auth::check()) {
            $title = '<a class="icon-admin" title="' . I18N::translate('Preferences') . '" href="block_edit.php?block_id=' . $block_id . '&amp;ged=' . $WT_TREE->getNameHtml() . '&amp;ctype=' . $ctype . '"></a>';
        } else {
            $title = '';
        }
        $title .= $this->getTitle();
        $table_id = Uuid::uuid4();
        // create a unique ID
        $controller->addExternalJavascript(WT_JQUERY_DATATABLES_JS_URL)->addInlineJavascript('
			jQuery("#' . $table_id . '").dataTable({
				dom: \'t\',
				' . I18N::datatablesI18N() . ',
				autoWidth: false,
				paginate: false,
				lengthChange: false,
				filter: false,
				info: true,
				jQueryUI: true,
				columns: [
					null,
					null,
					null,
					null
				]
			});
			jQuery("#' . $table_id . '").css("visibility", "visible");
			jQuery(".loading-image").css("display", "none");
		');
        $content = '';
        $content .= '<div class="loading-image">&nbsp;</div>';
        $content .= '<table id="' . $table_id . '" style="visibility:hidden;">';
        $content .= '<thead><tr>';
        $content .= '<th>' . GedcomTag::getLabel('DATE') . '</th>';
        $content .= '<th>' . I18N::translate('Record') . '</th>';
        $content .= '<th>' . I18N::translate('Username') . '</th>';
        $content .= '<th>' . GedcomTag::getLabel('TEXT') . '</th>';
        $content .= '</tr></thead><tbody>';
        $found = false;
        $end_jd = $show_future ? 99999999 : WT_CLIENT_JD;
        $xrefs = Database::prepare("SELECT DISTINCT d_gid FROM `##dates`" . " WHERE d_file = :tree_id AND d_fact = '_TODO' AND d_julianday1 < :jd")->execute(array('tree_id' => $WT_TREE->getTreeId(), 'jd' => $end_jd))->fetchOneColumn();
        $facts = array();
        foreach ($xrefs as $xref) {
            $record = GedcomRecord::getInstance($xref, $WT_TREE);
            if ($record->canShow()) {
                foreach ($record->getFacts('_TODO') as $fact) {
                    $facts[] = $fact;
                }
            }
        }
        foreach ($facts as $fact) {
            $record = $fact->getParent();
            $user_name = $fact->getAttribute('_WT_USER');
            if ($user_name === Auth::user()->getUserName() || !$user_name && $show_unassigned || $user_name && $show_other) {
                $content .= '<tr>';
                $content .= '<td data-sort="' . $fact->getDate()->julianDay() . '">' . $fact->getDate()->display() . '</td>';
                $content .= '<td data-sort="' . Filter::escapeHtml($record->getSortName()) . '"><a href="' . $record->getHtmlUrl() . '">' . $record->getFullName() . '</a></td>';
                $content .= '<td>' . $user_name . '</td>';
                $content .= '<td dir="auto">' . $fact->getValue() . '</td>';
                $content .= '</tr>';
                $found = true;
            }
        }
        $content .= '</tbody></table>';
        if (!$found) {
            $content .= '<p>' . I18N::translate('There are no research tasks in this family tree.') . '</p>';
        }
        if ($template) {
            if ($block) {
                $class .= ' small_inner_block';
            }
            return Theme::theme()->formatBlock($id, $title, $class, $content);
        } else {
            return $content;
        }
    }
コード例 #14
0
            $diff_lines = array();
            foreach ($differences as $difference) {
                switch ($difference[1]) {
                    case MyersDiff::DELETE:
                        $diff_lines[] = '<del>' . $difference[0] . '</del>';
                        break;
                    case MyersDiff::INSERT:
                        $diff_lines[] = '<ins>' . $difference[0] . '</ins>';
                        break;
                    default:
                        $diff_lines[] = $difference[0];
                }
            }
            // Only convert valid xrefs to links
            $data[] = array($row->change_id, $row->change_time, I18N::translate($row->status), GedcomRecord::getInstance($row->xref, Tree::findByName($gedc)) ? "<a href='gedrecord.php?pid={$row->xref}&ged={$row->gedcom_name}'>{$row->xref}</a>" : $row->xref, '<div class="gedcom-data" dir="ltr">' . preg_replace_callback('/@(' . WT_REGEX_XREF . ')@/', function ($match) use($gedc) {
                return GedcomRecord::getInstance($match[1], Tree::findByName($gedc)) ? "<a href='#' onclick='return edit_raw(\"{$match[1]}\");'>{$match[0]}</a>" : $match[0];
            }, implode("\n", $diff_lines)) . '</div>', $row->user_name, $row->gedcom_name);
        }
        header('Content-type: application/json');
        // See http://www.datatables.net/usage/server-side
        echo json_encode(array('draw' => Filter::getInteger('draw'), 'recordsTotal' => $recordsTotal, 'recordsFiltered' => $recordsFiltered, 'data' => $data));
        return;
}
$controller->pageHeader()->addExternalJavascript(WT_JQUERY_DATATABLES_JS_URL)->addExternalJavascript(WT_DATATABLES_BOOTSTRAP_JS_URL)->addExternalJavascript(WT_MOMENT_JS_URL)->addExternalJavascript(WT_BOOTSTRAP_DATETIMEPICKER_JS_URL)->addInlineJavascript('
		jQuery(".table-site-changes").dataTable( {
			processing: true,
			serverSide: true,
			ajax: "' . WT_BASE_URL . WT_SCRIPT_NAME . '?action=load_json&from=' . $from . '&to=' . $to . '&type=' . $type . '&oldged=' . rawurlencode($oldged) . '&newged=' . rawurlencode($newged) . '&xref=' . rawurlencode($xref) . '&user='******'&gedc=' . rawurlencode($gedc) . '",
			' . I18N::datatablesI18N(array(10, 20, 50, 100, 500, 1000, -1)) . ',
			sorting: [[ 0, "desc" ]],
			pageLength: ' . Auth::user()->getPreference('admin_site_change_page_size', 10) . ',
コード例 #15
0
 /**
  * Generate the HTML content of this block.
  *
  * @param int      $block_id
  * @param bool     $template
  * @param string[] $cfg
  *
  * @return string
  */
 public function getBlock($block_id, $template = true, $cfg = array())
 {
     global $ctype, $WT_TREE;
     $sendmail = $this->getBlockSetting($block_id, 'sendmail', '1');
     $days = $this->getBlockSetting($block_id, 'days', '1');
     $block = $this->getBlockSetting($block_id, 'block', '1');
     foreach (array('days', 'sendmail', 'block') as $name) {
         if (array_key_exists($name, $cfg)) {
             ${$name} = $cfg[$name];
         }
     }
     $changes = Database::prepare("SELECT 1" . " FROM `##change`" . " WHERE status='pending'" . " LIMIT 1")->fetchOne();
     if ($changes === '1' && $sendmail === '1') {
         // There are pending changes - tell moderators/managers/administrators about them.
         if (WT_TIMESTAMP - Site::getPreference('LAST_CHANGE_EMAIL') > 60 * 60 * 24 * $days) {
             // Which users have pending changes?
             foreach (User::all() as $user) {
                 if ($user->getPreference('contactmethod') !== 'none') {
                     foreach (Tree::getAll() as $tree) {
                         if ($tree->hasPendingEdit() && Auth::isManager($tree, $user)) {
                             I18N::init($user->getPreference('language'));
                             Mail::systemMessage($tree, $user, I18N::translate('Pending changes'), I18N::translate('There are pending changes for you to moderate.') . Mail::EOL . Mail::EOL . '<a href="' . WT_BASE_URL . 'index.php?ged=' . $WT_TREE->getNameUrl() . '">' . WT_BASE_URL . 'index.php?ged=' . $WT_TREE->getNameUrl() . '</a>');
                             I18N::init(WT_LOCALE);
                         }
                     }
                 }
             }
             Site::setPreference('LAST_CHANGE_EMAIL', WT_TIMESTAMP);
         }
     }
     if (Auth::isEditor($WT_TREE) && $WT_TREE->hasPendingEdit()) {
         $id = $this->getName() . $block_id;
         $class = $this->getName() . '_block';
         if ($ctype === 'user' || Auth::isManager($WT_TREE)) {
             $title = '<a class="icon-admin" title="' . I18N::translate('Configure') . '" href="block_edit.php?block_id=' . $block_id . '&amp;ged=' . $WT_TREE->getNameHtml() . '&amp;ctype=' . $ctype . '"></a>';
         } else {
             $title = '';
         }
         $title .= $this->getTitle();
         $content = '';
         if (Auth::isModerator($WT_TREE)) {
             $content .= "<a href=\"#\" onclick=\"window.open('edit_changes.php','_blank', chan_window_specs); return false;\">" . I18N::translate('There are pending changes for you to moderate.') . "</a><br>";
         }
         if ($sendmail === '1') {
             $content .= I18N::translate('Last email reminder was sent ') . FunctionsDate::formatTimestamp(Site::getPreference('LAST_CHANGE_EMAIL')) . "<br>";
             $content .= I18N::translate('Next email reminder will be sent after ') . FunctionsDate::formatTimestamp(Site::getPreference('LAST_CHANGE_EMAIL') + 60 * 60 * 24 * $days) . "<br><br>";
         }
         $content .= '<ul>';
         $changes = Database::prepare("SELECT xref" . " FROM  `##change`" . " WHERE status='pending'" . " AND   gedcom_id=?" . " GROUP BY xref")->execute(array($WT_TREE->getTreeId()))->fetchAll();
         foreach ($changes as $change) {
             $record = GedcomRecord::getInstance($change->xref, $WT_TREE);
             if ($record->canShow()) {
                 $content .= '<li><a href="' . $record->getHtmlUrl() . '">' . $record->getFullName() . '</a></li>';
             }
         }
         $content .= '</ul>';
         if ($template) {
             if ($block) {
                 $class .= ' small_inner_block';
             }
             return Theme::theme()->formatBlock($id, $title, $class, $content);
         } else {
             return $content;
         }
     }
 }
コード例 #16
0
 /**
  * XML </ Relatives>
  */
 private function relativesEndHandler()
 {
     global $report, $WT_TREE;
     $this->process_repeats--;
     if ($this->process_repeats > 0) {
         return;
     }
     // Check if there is any relatives
     if (count($this->list) > 0) {
         $lineoffset = 0;
         foreach ($this->repeats_stack as $rep) {
             $lineoffset += $rep[1];
         }
         //-- read the xml from the file
         $lines = file($report);
         while (strpos($lines[$lineoffset + $this->repeat_bytes], "<Relatives") === false && $lineoffset + $this->repeat_bytes > 0) {
             $lineoffset--;
         }
         $lineoffset++;
         $reportxml = "<tempdoc>\n";
         $line_nr = $lineoffset + $this->repeat_bytes;
         // Relatives Level counter
         $count = 1;
         while (0 < $count) {
             if (strpos($lines[$line_nr], "<Relatives") !== false) {
                 $count++;
             } elseif (strpos($lines[$line_nr], "</Relatives") !== false) {
                 $count--;
             }
             if (0 < $count) {
                 $reportxml .= $lines[$line_nr];
             }
             $line_nr++;
         }
         // No need to drag this
         unset($lines);
         $reportxml .= "</tempdoc>\n";
         // Save original values
         array_push($this->parser_stack, $this->parser);
         $oldgedrec = $this->gedrec;
         $this->list_total = count($this->list);
         $this->list_private = 0;
         foreach ($this->list as $key => $value) {
             if (isset($value->generation)) {
                 $this->generation = $value->generation;
             }
             $tmp = GedcomRecord::getInstance($key, $WT_TREE);
             $this->gedrec = $tmp->privatizeGedcom(Auth::accessLevel($WT_TREE));
             $repeat_parser = xml_parser_create();
             $this->parser = $repeat_parser;
             xml_parser_set_option($repeat_parser, XML_OPTION_CASE_FOLDING, false);
             xml_set_element_handler($repeat_parser, array($this, 'startElement'), array($this, 'endElement'));
             xml_set_character_data_handler($repeat_parser, array($this, 'characterData'));
             if (!xml_parse($repeat_parser, $reportxml, true)) {
                 throw new \DomainException(sprintf("RelativesEHandler XML error: %s at line %d", xml_error_string(xml_get_error_code($repeat_parser)), xml_get_current_line_number($repeat_parser)));
             }
             xml_parser_free($repeat_parser);
         }
         // Clean up the list array
         $this->list = array();
         $this->parser = array_pop($this->parser_stack);
         $this->gedrec = $oldgedrec;
     }
     list($this->repeats, $this->repeat_bytes) = array_pop($this->repeats_stack);
 }
コード例 #17
0
ファイル: placelist.php プロジェクト: jflash/webtrees
             echo 'colspan="2"';
         }
         echo ' style="text-align: center;">';
         echo '<a href="', $place->getURL(), '&amp;action=show" class="formField">', $place->getPlaceName(), '</a>';
         echo '</td></tr>';
     }
     echo '</table>';
 }
 echo '</td></tr></table>';
 if ($place_id && $action == 'show') {
     // -- array of names
     $myindilist = array();
     $myfamlist = array();
     $positions = Database::prepare("SELECT DISTINCT pl_gid FROM `##placelinks` WHERE pl_p_id=? AND pl_file=?")->execute(array($place_id, $WT_TREE->getTreeId()))->fetchOneColumn();
     foreach ($positions as $position) {
         $record = GedcomRecord::getInstance($position, $WT_TREE);
         if ($record && $record->canShow()) {
             if ($record instanceof Individual) {
                 $myindilist[] = $record;
             }
             if ($record instanceof Family) {
                 $myfamlist[] = $record;
             }
         }
     }
     echo '<br>';
     //-- display results
     $controller->addInlineJavascript('jQuery("#places-tabs").tabs();')->addInlineJavascript('jQuery("#places-tabs").css("visibility", "visible");')->addInlineJavascript('jQuery(".loading-image").css("display", "none");');
     echo '<div class="loading-image">&nbsp;</div>';
     echo '<div id="places-tabs"><ul>';
     if ($myindilist) {
コード例 #18
0
 /**
  * Generate the HTML content of this block.
  *
  * @param int      $block_id
  * @param bool     $template
  * @param string[] $cfg
  *
  * @return string
  */
 public function getBlock($block_id, $template = true, $cfg = array())
 {
     global $ctype, $controller, $WT_TREE;
     $action = Filter::get('action');
     switch ($action) {
         case 'deletefav':
             $favorite_id = Filter::getInteger('favorite_id');
             if ($favorite_id) {
                 self::deleteFavorite($favorite_id);
             }
             break;
         case 'addfav':
             $gid = Filter::get('gid', WT_REGEX_XREF);
             $favnote = Filter::get('favnote');
             $url = Filter::getUrl('url');
             $favtitle = Filter::get('favtitle');
             if ($gid) {
                 $record = GedcomRecord::getInstance($gid, $WT_TREE);
                 if ($record && $record->canShow()) {
                     self::addFavorite(array('user_id' => $ctype === 'user' ? Auth::id() : null, 'gedcom_id' => $WT_TREE->getTreeId(), 'gid' => $record->getXref(), 'type' => $record::RECORD_TYPE, 'url' => null, 'note' => $favnote, 'title' => $favtitle));
                 }
             } elseif ($url) {
                 self::addFavorite(array('user_id' => $ctype === 'user' ? Auth::id() : null, 'gedcom_id' => $WT_TREE->getTreeId(), 'gid' => null, 'type' => 'URL', 'url' => $url, 'note' => $favnote, 'title' => $favtitle ? $favtitle : $url));
             }
             break;
     }
     $block = $this->getBlockSetting($block_id, 'block', '0');
     foreach (array('block') as $name) {
         if (array_key_exists($name, $cfg)) {
             ${$name} = $cfg[$name];
         }
     }
     $userfavs = $this->getFavorites($ctype === 'user' ? Auth::id() : $WT_TREE->getTreeId());
     if (!is_array($userfavs)) {
         $userfavs = array();
     }
     $id = $this->getName() . $block_id;
     $class = $this->getName() . '_block';
     $title = $this->getTitle();
     if (Auth::check()) {
         $controller->addExternalJavascript(WT_AUTOCOMPLETE_JS_URL)->addInlineJavascript('autocomplete();');
     }
     $content = '';
     if ($userfavs) {
         foreach ($userfavs as $key => $favorite) {
             if (isset($favorite['id'])) {
                 $key = $favorite['id'];
             }
             $removeFavourite = '<a class="font9" href="index.php?ctype=' . $ctype . '&amp;ged=' . $WT_TREE->getNameHtml() . '&amp;action=deletefav&amp;favorite_id=' . $key . '" onclick="return confirm(\'' . I18N::translate('Are you sure you want to remove this item from your list of favorites?') . '\');">' . I18N::translate('Remove') . '</a> ';
             if ($favorite['type'] == 'URL') {
                 $content .= '<div id="boxurl' . $key . '.0" class="person_box">';
                 if ($ctype == 'user' || Auth::isManager($WT_TREE)) {
                     $content .= $removeFavourite;
                 }
                 $content .= '<a href="' . $favorite['url'] . '"><b>' . $favorite['title'] . '</b></a>';
                 $content .= '<br>' . $favorite['note'];
                 $content .= '</div>';
             } else {
                 $record = GedcomRecord::getInstance($favorite['gid'], $WT_TREE);
                 if ($record && $record->canShow()) {
                     if ($record instanceof Individual) {
                         $content .= '<div id="box' . $favorite["gid"] . '.0" class="person_box action_header';
                         switch ($record->getsex()) {
                             case 'M':
                                 break;
                             case 'F':
                                 $content .= 'F';
                                 break;
                             default:
                                 $content .= 'NN';
                                 break;
                         }
                         $content .= '">';
                         if ($ctype == "user" || Auth::isManager($WT_TREE)) {
                             $content .= $removeFavourite;
                         }
                         $content .= Theme::theme()->individualBoxLarge($record);
                         $content .= $favorite['note'];
                         $content .= '</div>';
                     } else {
                         $content .= '<div id="box' . $favorite['gid'] . '.0" class="person_box">';
                         if ($ctype == 'user' || Auth::isManager($WT_TREE)) {
                             $content .= $removeFavourite;
                         }
                         $content .= $record->formatList('span');
                         $content .= '<br>' . $favorite['note'];
                         $content .= '</div>';
                     }
                 }
             }
         }
     }
     if ($ctype == 'user' || Auth::isManager($WT_TREE)) {
         $uniqueID = Uuid::uuid4();
         // This block can theoretically appear multiple times, so use a unique ID.
         $content .= '<div class="add_fav_head">';
         $content .= '<a href="#" onclick="return expand_layer(\'add_fav' . $uniqueID . '\');">' . I18N::translate('Add a new favorite') . '<i id="add_fav' . $uniqueID . '_img" class="icon-plus"></i></a>';
         $content .= '</div>';
         $content .= '<div id="add_fav' . $uniqueID . '" style="display: none;">';
         $content .= '<form name="addfavform" method="get" action="index.php">';
         $content .= '<input type="hidden" name="action" value="addfav">';
         $content .= '<input type="hidden" name="ctype" value="' . $ctype . '">';
         $content .= '<input type="hidden" name="ged" value="' . $WT_TREE->getNameHtml() . '">';
         $content .= '<div class="add_fav_ref">';
         $content .= '<input type="radio" name="fav_category" value="record" checked onclick="jQuery(\'#gid' . $uniqueID . '\').removeAttr(\'disabled\'); jQuery(\'#url, #favtitle\').attr(\'disabled\',\'disabled\').val(\'\');">';
         $content .= '<label for="gid' . $uniqueID . '">' . I18N::translate('Enter an individual, family, or source ID') . '</label>';
         $content .= '<input class="pedigree_form" data-autocomplete-type="IFSRO" type="text" name="gid" id="gid' . $uniqueID . '" size="5" value="">';
         $content .= ' ' . FunctionsPrint::printFindIndividualLink('gid' . $uniqueID);
         $content .= ' ' . FunctionsPrint::printFindFamilyLink('gid' . $uniqueID);
         $content .= ' ' . FunctionsPrint::printFindSourceLink('gid' . $uniqueID);
         $content .= ' ' . FunctionsPrint::printFindRepositoryLink('gid' . $uniqueID);
         $content .= ' ' . FunctionsPrint::printFindNoteLink('gid' . $uniqueID);
         $content .= ' ' . FunctionsPrint::printFindMediaLink('gid' . $uniqueID);
         $content .= '</div>';
         $content .= '<div class="add_fav_url">';
         $content .= '<input type="radio" name="fav_category" value="url" onclick="jQuery(\'#url, #favtitle\').removeAttr(\'disabled\'); jQuery(\'#gid' . $uniqueID . '\').attr(\'disabled\',\'disabled\').val(\'\');">';
         $content .= '<input type="text" name="url" id="url" size="20" value="" placeholder="' . GedcomTag::getLabel('URL') . '" disabled> ';
         $content .= '<input type="text" name="favtitle" id="favtitle" size="20" value="" placeholder="' . I18N::translate('Title') . '" disabled>';
         $content .= '<p>' . I18N::translate('Enter an optional note about this favorite') . '</p>';
         $content .= '<textarea name="favnote" rows="6" cols="50"></textarea>';
         $content .= '</div>';
         $content .= '<input type="submit" value="' . I18N::translate('Add') . '">';
         $content .= '</form></div>';
     }
     if ($template) {
         if ($block) {
             $class .= ' small_inner_block';
         }
         return Theme::theme()->formatBlock($id, $title, $class, $content);
     } else {
         return $content;
     }
 }
コード例 #19
0
ファイル: addmedia.php プロジェクト: pal-saugstad/webtrees
     // Insert the 1 FILE xxx record into the arrays used by function FunctionsEdit::handle_updatesges()
     $glevels = array_merge(array('1'), $glevels);
     $tag = array_merge(array('FILE'), $tag);
     $islink = array_merge(array(0), $islink);
     $text = array_merge(array($newFilename), $text);
     $record = GedcomRecord::getInstance($pid, $WT_TREE);
     $newrec = "0 @{$pid}@ OBJE\n";
     $newrec = FunctionsEdit::handleUpdates($newrec);
     $record->updateRecord($newrec, $update_CHAN);
     if ($move_file) {
         // We've moved a file. Therefore we must approve the change, as rejecting
         // the change will create broken references.
         FunctionsImport::acceptAllChanges($record->getXref(), $record->getTree()->getTreeId());
     }
     if ($pid && $linktoid) {
         $record = GedcomRecord::getInstance($linktoid, $WT_TREE);
         $record->createFact('1 OBJE @' . $pid . '@', true);
         Log::addEditLog('Media ID ' . $pid . " successfully added to {$linktoid}.");
     }
     $controller->pageHeader();
     if ($messages) {
         echo '<button onclick="closePopupAndReloadParent();">', I18N::translate('close'), '</button>';
     } else {
         $controller->addInlineJavascript('closePopupAndReloadParent();');
     }
     return;
 case 'showmediaform':
     $controller->setPageTitle(I18N::translate('Create a new media object'));
     $action = 'create';
     break;
 case 'editmedia':
コード例 #20
0
ファイル: Stats.php プロジェクト: AlexSnet/webtrees
 /**
  * Events
  *
  * @param string $type
  * @param string $direction
  * @param string $facts
  *
  * @return string
  */
 private function eventQuery($type, $direction, $facts)
 {
     $eventTypes = array('BIRT' => I18N::translate('birth'), 'DEAT' => I18N::translate('death'), 'MARR' => I18N::translate('marriage'), 'ADOP' => I18N::translate('adoption'), 'BURI' => I18N::translate('burial'), 'CENS' => I18N::translate('census added'));
     $fact_query = "IN ('" . str_replace('|', "','", $facts) . "')";
     if ($direction != 'ASC') {
         $direction = 'DESC';
     }
     $rows = $this->runSql('' . ' SELECT SQL_CACHE' . ' d_gid AS id,' . ' d_year AS year,' . ' d_fact AS fact,' . ' d_type AS type' . ' FROM' . " `##dates`" . ' WHERE' . " d_file={$this->tree->getTreeId()} AND" . " d_gid<>'HEAD' AND" . " d_fact {$fact_query} AND" . ' d_julianday1<>0' . ' ORDER BY' . " d_julianday1 {$direction}, d_type LIMIT 1");
     if (!isset($rows[0])) {
         return '';
     }
     $row = $rows[0];
     $record = GedcomRecord::getInstance($row['id'], $this->tree);
     switch ($type) {
         default:
         case 'full':
             if ($record->canShow()) {
                 $result = $record->formatList('span', false, $record->getFullName());
             } else {
                 $result = I18N::translate('This information is private and cannot be shown.');
             }
             break;
         case 'year':
             $date = new Date($row['type'] . ' ' . $row['year']);
             $result = $date->display();
             break;
         case 'type':
             if (isset($eventTypes[$row['fact']])) {
                 $result = $eventTypes[$row['fact']];
             } else {
                 $result = GedcomTag::getLabel($row['fact']);
             }
             break;
         case 'name':
             $result = "<a href=\"" . $record->getHtmlUrl() . "\">" . $record->getFullName() . "</a>";
             break;
         case 'place':
             $fact = $record->getFirstFact($row['fact']);
             if ($fact) {
                 $result = FunctionsPrint::formatFactPlace($fact, true, true, true);
             } else {
                 $result = I18N::translate('Private');
             }
             break;
     }
     return $result;
 }
コード例 #21
0
 /**
  * Print a row for the notes tab on the individual page.
  *
  * @param Fact $fact
  * @param int $level
  */
 public static function printMainNotes(Fact $fact, $level)
 {
     $factrec = $fact->getGedcom();
     $fact_id = $fact->getFactId();
     $parent = $fact->getParent();
     $pid = $parent->getXref();
     if ($fact->isPendingAddition()) {
         $styleadd = ' new';
         $can_edit = $level == 1 && $fact->canEdit();
     } elseif ($fact->isPendingDeletion()) {
         $styleadd = ' old';
         $can_edit = false;
     } else {
         $styleadd = '';
         $can_edit = $level == 1 && $fact->canEdit();
     }
     $ct = preg_match_all("/{$level} NOTE (.*)/", $factrec, $match, PREG_SET_ORDER);
     for ($j = 0; $j < $ct; $j++) {
         // Note object, or inline note?
         if (preg_match("/{$level} NOTE @(.*)@/", $match[$j][0], $nmatch)) {
             $note = Note::getInstance($nmatch[1], $fact->getParent()->getTree());
             if ($note && !$note->canShow()) {
                 continue;
             }
         } else {
             $note = null;
         }
         if ($level >= 2) {
             echo '<tr class="row_note2"><td class="descriptionbox rela ', $styleadd, ' width20">';
         } else {
             echo '<tr><td class="descriptionbox ', $styleadd, ' width20">';
         }
         if ($can_edit) {
             echo '<a onclick="return edit_record(\'', $pid, '\', \'', $fact_id, '\');" href="#" title="', I18N::translate('Edit'), '">';
             if ($level < 2) {
                 if ($fact->getParent()->getTree()->getPreference('SHOW_FACT_ICONS')) {
                     echo '<i class="icon-note"></i> ';
                 }
                 if ($note) {
                     echo GedcomTag::getLabel('SHARED_NOTE');
                 } else {
                     echo GedcomTag::getLabel('NOTE');
                 }
                 echo '</a>';
                 echo '<div class="editfacts">';
                 echo "<div class=\"editlink\"><a class=\"editicon\" onclick=\"return edit_record('{$pid}', '{$fact_id}');\" href=\"#\" title=\"" . I18N::translate('Edit') . "\"><span class=\"link_text\">" . I18N::translate('Edit') . "</span></a></div>";
                 echo '<div class="copylink"><a class="copyicon" href="#" onclick="return copy_fact(\'', $pid, '\', \'', $fact_id, '\');" title="' . I18N::translate('Copy') . '"><span class="link_text">' . I18N::translate('Copy') . '</span></a></div>';
                 echo "<div class=\"deletelink\"><a class=\"deleteicon\" onclick=\"return delete_fact('" . I18N::translate('Are you sure you want to delete this fact?') . "', '{$pid}', '{$fact_id}');\" href=\"#\" title=\"" . I18N::translate('Delete') . "\"><span class=\"link_text\">" . I18N::translate('Delete') . "</span></a></div>";
                 if ($note) {
                     echo '<a class="icon-note" href="', $note->getHtmlUrl(), '" title="' . I18N::translate('View') . '"><span class="link_text">' . I18N::translate('View') . '</span></a>';
                 }
                 echo '</div>';
             }
         } else {
             if ($level < 2) {
                 if ($fact->getParent()->getTree()->getPreference('SHOW_FACT_ICONS')) {
                     echo '<i class="icon-note"></i> ';
                 }
                 if ($note) {
                     echo GedcomTag::getLabel('SHARED_NOTE');
                 } else {
                     echo GedcomTag::getLabel('NOTE');
                 }
             }
             $factlines = explode("\n", $factrec);
             // 1 BIRT Y\n2 NOTE ...
             $factwords = explode(" ", $factlines[0]);
             // 1 BIRT Y
             $factname = $factwords[1];
             // BIRT
             $parent = GedcomRecord::getInstance($pid, $fact->getParent()->getTree());
             if ($factname == 'EVEN' || $factname == 'FACT') {
                 // Add ' EVEN' to provide sensible output for an event with an empty TYPE record
                 $ct = preg_match("/2 TYPE (.*)/", $factrec, $ematch);
                 if ($ct > 0) {
                     $factname = trim($ematch[1]);
                     echo $factname;
                 } else {
                     echo GedcomTag::getLabel($factname, $parent);
                 }
             } elseif ($factname != 'NOTE') {
                 // Note is already printed
                 echo GedcomTag::getLabel($factname, $parent);
                 if ($note) {
                     echo '<div class="editfacts"><a class="icon-note" href="', $note->getHtmlUrl(), '" title="' . I18N::translate('View') . '"><span class="link_text">' . I18N::translate('View') . '</span></a></div>';
                 }
             }
         }
         echo '</td>';
         if ($note) {
             // Note objects
             if (Module::getModuleByName('GEDFact_assistant')) {
                 // If Census assistant installed, allow it to format the note
                 $text = CensusAssistantModule::formatCensusNote($note);
             } else {
                 $text = Filter::formatText($note->getNote(), $fact->getParent()->getTree());
             }
         } else {
             // Inline notes
             $nrec = Functions::getSubRecord($level, "{$level} NOTE", $factrec, $j + 1);
             $text = $match[$j][1] . Functions::getCont($level + 1, $nrec);
             $text = Filter::formatText($text, $fact->getParent()->getTree());
         }
         echo '<td class="optionbox', $styleadd, ' wrap">';
         echo $text;
         if (!empty($noterec)) {
             echo self::printFactSources($noterec, 1);
         }
         // 2 RESN tags.  Note, there can be more than one, such as "privacy" and "locked"
         if (preg_match_all("/\n2 RESN (.+)/", $factrec, $matches)) {
             foreach ($matches[1] as $match) {
                 echo '<br><span class="label">', GedcomTag::getLabel('RESN'), ':</span> <span class="field">';
                 switch ($match) {
                     case 'none':
                         // Note: "2 RESN none" is not valid gedcom, and the GUI will not let you add it.
                         // However, webtrees privacy rules will interpret it as "show an otherwise private fact to public".
                         echo '<i class="icon-resn-none"></i> ', I18N::translate('Show to visitors');
                         break;
                     case 'privacy':
                         echo '<i class="icon-resn-privacy"></i> ', I18N::translate('Show to members');
                         break;
                     case 'confidential':
                         echo '<i class="icon-resn-confidential"></i> ', I18N::translate('Show to managers');
                         break;
                     case 'locked':
                         echo '<i class="icon-resn-locked"></i> ', I18N::translate('Only managers can edit');
                         break;
                     default:
                         echo $match;
                         break;
                 }
                 echo '</span>';
             }
         }
         echo '</td></tr>';
     }
 }
コード例 #22
0
 /**
  * add a new tag input field
  *
  * called for each fact to be edited on a form.
  * Fact level=0 means a new empty form : data are POSTed by name
  * else data are POSTed using arrays :
  * glevels[] : tag level
  *  islink[] : tag is a link
  *     tag[] : tag name
  *    text[] : tag value
  *
  * @param string $tag fact record to edit (eg 2 DATE xxxxx)
  * @param string $upperlevel optional upper level tag (eg BIRT)
  * @param string $label An optional label to echo instead of the default
  * @param string $extra optional text to display after the input field
  * @param Individual $person For male/female translations
  *
  * @return string
  */
 public static function addSimpleTag($tag, $upperlevel = '', $label = '', $extra = null, Individual $person = null)
 {
     global $tags, $main_fact, $xref, $bdm, $action, $WT_TREE;
     // Keep track of SOUR fields, so we can reference them in subsequent PAGE fields.
     static $source_element_id;
     $subnamefacts = array('NPFX', 'GIVN', 'SPFX', 'SURN', 'NSFX', '_MARNM_SURN');
     preg_match('/^(?:(\\d+) (' . WT_REGEX_TAG . ') ?(.*))/', $tag, $match);
     list(, $level, $fact, $value) = $match;
     $level = (int) $level;
     // element name : used to POST data
     if ($level === 0) {
         if ($upperlevel) {
             $element_name = $upperlevel . '_' . $fact;
         } else {
             $element_name = $fact;
         }
     } else {
         $element_name = 'text[]';
     }
     if ($level === 1) {
         $main_fact = $fact;
     }
     // element id : used by javascript functions
     if ($level === 0) {
         $element_id = $fact;
     } else {
         $element_id = $fact . Uuid::uuid4();
     }
     if ($upperlevel) {
         $element_id = $upperlevel . '_' . $fact . Uuid::uuid4();
     }
     // field value
     $islink = substr($value, 0, 1) === '@' && substr($value, 0, 2) !== '@#';
     if ($islink) {
         $value = trim(substr($tag, strlen($fact) + 3), ' @\\r');
     } else {
         $value = (string) substr($tag, strlen($fact) + 3);
     }
     if ($fact === 'REPO' || $fact === 'SOUR' || $fact === 'OBJE' || $fact === 'FAMC') {
         $islink = true;
     }
     if ($fact === 'SHARED_NOTE_EDIT' || $fact === 'SHARED_NOTE') {
         $islink = true;
         $fact = 'NOTE';
     }
     // label
     echo '<tr id="', $element_id, '_tr"';
     if ($fact === 'MAP' || ($fact === 'LATI' || $fact === 'LONG') && $value === '') {
         echo ' style="display:none;"';
     }
     echo '>';
     if (in_array($fact, $subnamefacts) || $fact === 'LATI' || $fact === 'LONG') {
         echo '<td class="optionbox wrap width25">';
     } else {
         echo '<td class="descriptionbox wrap width25">';
     }
     // tag name
     if ($label) {
         echo $label;
     } elseif ($upperlevel) {
         echo GedcomTag::getLabel($upperlevel . ':' . $fact);
     } else {
         echo GedcomTag::getLabel($fact);
     }
     // If using GEDFact-assistant window
     if ($action === 'addnewnote_assisted') {
         // Do not print on GEDFact Assistant window
     } else {
         // Not all facts have help text.
         switch ($fact) {
             case 'NAME':
                 if ($upperlevel !== 'REPO' && $upperlevel !== 'UNKNOWN') {
                     echo FunctionsPrint::helpLink($fact);
                 }
                 break;
             case 'DATE':
             case 'PLAC':
             case 'RESN':
             case 'ROMN':
             case 'SURN':
             case '_HEB':
                 echo FunctionsPrint::helpLink($fact);
                 break;
         }
     }
     // tag level
     if ($level > 0) {
         if ($fact === 'TEXT' && $level > 1) {
             echo '<input type="hidden" name="glevels[]" value="', $level - 1, '">';
             echo '<input type="hidden" name="islink[]" value="0">';
             echo '<input type="hidden" name="tag[]" value="DATA">';
             // leave data text[] value empty because the following TEXT line will cause the DATA to be added
             echo '<input type="hidden" name="text[]" value="">';
         }
         echo '<input type="hidden" name="glevels[]" value="', $level, '">';
         echo '<input type="hidden" name="islink[]" value="', $islink, '">';
         echo '<input type="hidden" name="tag[]" value="', $fact, '">';
     }
     echo '</td>';
     // value
     echo '<td class="optionbox wrap">';
     // retrieve linked NOTE
     if ($fact === 'NOTE' && $islink) {
         $note1 = Note::getInstance($value, $WT_TREE);
         if ($note1) {
             $noterec = $note1->getGedcom();
             preg_match('/' . $value . '/i', $noterec, $notematch);
             $value = $notematch[0];
         }
     }
     // Show names for spouses in MARR/HUSB/AGE and MARR/WIFE/AGE
     if ($fact === 'HUSB' || $fact === 'WIFE') {
         $family = Family::getInstance($xref, $WT_TREE);
         if ($family) {
             $spouse_link = $family->getFirstFact($fact);
             if ($spouse_link) {
                 $spouse = $spouse_link->getTarget();
                 if ($spouse) {
                     echo $spouse->getFullName();
                 }
             }
         }
     }
     if (in_array($fact, Config::emptyFacts()) && ($value === '' || $value === 'Y' || $value === 'y')) {
         echo '<input type="hidden" id="', $element_id, '" name="', $element_name, '" value="', $value, '">';
         if ($level <= 1) {
             echo '<input type="checkbox" ';
             if ($value) {
                 echo 'checked';
             }
             echo ' onclick="document.getElementById(\'' . $element_id . '\').value = (this.checked) ? \'Y\' : \'\';">';
             echo I18N::translate('yes');
         }
         if ($fact === 'CENS' && $value === 'Y') {
             echo self::censusDateSelector(WT_LOCALE, $xref);
             if (Module::getModuleByName('GEDFact_assistant') && GedcomRecord::getInstance($xref, $WT_TREE) instanceof Individual) {
                 echo '<div></div><a href="#" style="display: none;" id="assistant-link" onclick="return activateCensusAssistant();">' . I18N::translate('Create a new shared note using assistant') . '</a></div>';
             }
         }
     } elseif ($fact === 'TEMP') {
         echo self::selectEditControl($element_name, GedcomCodeTemp::templeNames(), I18N::translate('No temple - living ordinance'), $value);
     } elseif ($fact === 'ADOP') {
         echo self::editFieldAdoption($element_name, $value, '', $person);
     } elseif ($fact === 'PEDI') {
         echo self::editFieldPedigree($element_name, $value, '', $person);
     } elseif ($fact === 'STAT') {
         echo self::selectEditControl($element_name, GedcomCodeStat::statusNames($upperlevel), '', $value);
     } elseif ($fact === 'RELA') {
         echo self::editFieldRelationship($element_name, strtolower($value));
     } elseif ($fact === 'QUAY') {
         echo self::selectEditControl($element_name, GedcomCodeQuay::getValues(), '', $value);
     } elseif ($fact === '_WT_USER') {
         echo self::editFieldUsername($element_name, $value);
     } elseif ($fact === 'RESN') {
         echo self::editFieldRestriction($element_name, $value);
     } elseif ($fact === '_PRIM') {
         echo '<select id="', $element_id, '" name="', $element_name, '" >';
         echo '<option value=""></option>';
         echo '<option value="Y" ';
         if ($value === 'Y') {
             echo ' selected';
         }
         echo '>', I18N::translate('always'), '</option>';
         echo '<option value="N" ';
         if ($value === 'N') {
             echo 'selected';
         }
         echo '>', I18N::translate('never'), '</option>';
         echo '</select>';
         echo '<p class="small text-muted">', I18N::translate('Use this image for charts and on the individual’s page.'), '</p>';
     } elseif ($fact === 'SEX') {
         echo '<select id="', $element_id, '" name="', $element_name, '"><option value="M" ';
         if ($value === 'M') {
             echo 'selected';
         }
         echo '>', I18N::translate('Male'), '</option><option value="F" ';
         if ($value === 'F') {
             echo 'selected';
         }
         echo '>', I18N::translate('Female'), '</option><option value="U" ';
         if ($value === 'U' || empty($value)) {
             echo 'selected';
         }
         echo '>', I18N::translateContext('unknown gender', 'Unknown'), '</option></select>';
     } elseif ($fact === 'TYPE' && $level === 3) {
         //-- Build the selector for the Media 'TYPE' Fact
         echo '<select name="text[]"><option selected value="" ></option>';
         $selectedValue = strtolower($value);
         if (!array_key_exists($selectedValue, GedcomTag::getFileFormTypes())) {
             echo '<option selected value="', Filter::escapeHtml($value), '" >', Filter::escapeHtml($value), '</option>';
         }
         foreach (GedcomTag::getFileFormTypes() as $typeName => $typeValue) {
             echo '<option value="', $typeName, '" ';
             if ($selectedValue === $typeName) {
                 echo 'selected';
             }
             echo '>', $typeValue, '</option>';
         }
         echo '</select>';
     } elseif ($fact === 'NAME' && $upperlevel !== 'REPO' && $upperlevel !== 'UNKNOWN' || $fact === '_MARNM') {
         // Populated in javascript from sub-tags
         echo '<input type="hidden" id="', $element_id, '" name="', $element_name, '" onchange="updateTextName(\'', $element_id, '\');" value="', Filter::escapeHtml($value), '" class="', $fact, '">';
         echo '<span id="', $element_id, '_display" dir="auto">', Filter::escapeHtml($value), '</span>';
         echo ' <a href="#edit_name" onclick="convertHidden(\'', $element_id, '\'); return false;" class="icon-edit_indi" title="' . I18N::translate('Edit name') . '"></a>';
     } else {
         // textarea
         if ($fact === 'TEXT' || $fact === 'ADDR' || $fact === 'NOTE' && !$islink) {
             echo '<textarea id="', $element_id, '" name="', $element_name, '" dir="auto">', Filter::escapeHtml($value), '</textarea><br>';
         } else {
             // text
             // If using GEDFact-assistant window
             if ($action === 'addnewnote_assisted') {
                 echo '<input type="text" id="', $element_id, '" name="', $element_name, '" value="', Filter::escapeHtml($value), '" style="width:4.1em;" dir="ltr"';
             } else {
                 echo '<input type="text" id="', $element_id, '" name="', $element_name, '" value="', Filter::escapeHtml($value), '" dir="ltr"';
             }
             echo ' class="', $fact, '"';
             if (in_array($fact, $subnamefacts)) {
                 echo ' onblur="updatewholename();" onkeyup="updatewholename();"';
             }
             // Extra markup for specific fact types
             switch ($fact) {
                 case 'ALIA':
                 case 'ASSO':
                 case '_ASSO':
                     echo ' data-autocomplete-type="ASSO" data-autocomplete-extra="input.DATE"';
                     break;
                 case 'DATE':
                     echo ' onblur="valid_date(this);" onmouseout="valid_date(this);"';
                     break;
                 case 'GIVN':
                     echo ' autofocus data-autocomplete-type="GIVN"';
                     break;
                 case 'LATI':
                     echo ' onblur="valid_lati_long(this, \'N\', \'S\');" onmouseout="valid_lati_long(this, \'N\', \'S\');"';
                     break;
                 case 'LONG':
                     echo ' onblur="valid_lati_long(this, \'E\', \'W\');" onmouseout="valid_lati_long(this, \'E\', \'W\');"';
                     break;
                 case 'NOTE':
                     // Shared notes. Inline notes are handled elsewhere.
                     echo ' data-autocomplete-type="NOTE"';
                     break;
                 case 'OBJE':
                     echo ' data-autocomplete-type="OBJE"';
                     break;
                 case 'PAGE':
                     echo ' data-autocomplete-type="PAGE" data-autocomplete-extra="#' . $source_element_id . '"';
                     break;
                 case 'PLAC':
                     echo ' data-autocomplete-type="PLAC"';
                     break;
                 case 'REPO':
                     echo ' data-autocomplete-type="REPO"';
                     break;
                 case 'SOUR':
                     $source_element_id = $element_id;
                     echo ' data-autocomplete-type="SOUR"';
                     break;
                 case 'SURN':
                 case '_MARNM_SURN':
                     echo ' data-autocomplete-type="SURN"';
                     break;
                 case 'TIME':
                     echo ' pattern="([0-1][0-9]|2[0-3]):[0-5][0-9](:[0-5][0-9])?" dir="ltr" placeholder="' . I18N::translate('hh:mm or hh:mm:ss') . '"';
                     break;
             }
             echo '>';
         }
         $tmp_array = array('TYPE', 'TIME', 'NOTE', 'SOUR', 'REPO', 'OBJE', 'ASSO', '_ASSO', 'AGE');
         // split PLAC
         if ($fact === 'PLAC') {
             echo '<div id="', $element_id, '_pop" style="display: inline;">';
             echo FunctionsPrint::printSpecialCharacterLink($element_id), ' ', FunctionsPrint::printFindPlaceLink($element_id);
             echo '<span  onclick="jQuery(\'tr[id^=', $upperlevel, '_LATI],tr[id^=', $upperlevel, '_LONG],tr[id^=LATI],tr[id^=LONG]\').toggle(\'fast\'); return false;" class="icon-target" title="', GedcomTag::getLabel('LATI'), ' / ', GedcomTag::getLabel('LONG'), '"></span>';
             echo '</div>';
             if (Module::getModuleByName('places_assistant')) {
                 \PlacesAssistantModule::setup_place_subfields($element_id);
                 \PlacesAssistantModule::print_place_subfields($element_id);
             }
         } elseif (!in_array($fact, $tmp_array)) {
             echo FunctionsPrint::printSpecialCharacterLink($element_id);
         }
     }
     // MARRiage TYPE : hide text field and show a selection list
     if ($fact === 'TYPE' && $level === 2 && $tags[0] === 'MARR') {
         echo '<script>';
         echo 'document.getElementById(\'', $element_id, '\').style.display=\'none\'';
         echo '</script>';
         echo '<select id="', $element_id, '_sel" onchange="document.getElementById(\'', $element_id, '\').value=this.value;" >';
         foreach (array('Unknown', 'Civil', 'Religious', 'Partners') as $key) {
             if ($key === 'Unknown') {
                 echo '<option value="" ';
             } else {
                 echo '<option value="', $key, '" ';
             }
             $a = strtolower($key);
             $b = strtolower($value);
             if ($b !== '' && strpos($a, $b) !== false || strpos($b, $a) !== false) {
                 echo 'selected';
             }
             echo '>', GedcomTag::getLabel('MARR_' . strtoupper($key)), '</option>';
         }
         echo '</select>';
     } elseif ($fact === 'TYPE' && $level === 0) {
         // NAME TYPE : hide text field and show a selection list
         $onchange = 'onchange="document.getElementById(\'' . $element_id . '\').value=this.value;"';
         echo self::editFieldNameType($element_name, $value, $onchange, $person);
         echo '<script>document.getElementById("', $element_id, '").style.display="none";</script>';
     }
     // popup links
     switch ($fact) {
         case 'DATE':
             echo self::printCalendarPopup($element_id);
             break;
         case 'FAMC':
         case 'FAMS':
             echo FunctionsPrint::printFindFamilyLink($element_id);
             break;
         case 'ALIA':
         case 'ASSO':
         case '_ASSO':
             echo FunctionsPrint::printFindIndividualLink($element_id, $element_id . '_description');
             break;
         case 'FILE':
             FunctionsPrint::printFindMediaLink($element_id, '0file');
             break;
         case 'SOUR':
             echo FunctionsPrint::printFindSourceLink($element_id, $element_id . '_description'), ' ', self::printAddNewSourceLink($element_id);
             //-- checkboxes to apply '1 SOUR' to BIRT/MARR/DEAT as '2 SOUR'
             if ($level === 1) {
                 echo '<br>';
                 switch ($WT_TREE->getPreference('PREFER_LEVEL2_SOURCES')) {
                     case '2':
                         // records
                         $level1_checked = 'checked';
                         $level2_checked = '';
                         break;
                     case '1':
                         // facts
                         $level1_checked = '';
                         $level2_checked = 'checked';
                         break;
                     case '0':
                         // none
                     // none
                     default:
                         $level1_checked = '';
                         $level2_checked = '';
                         break;
                 }
                 if (strpos($bdm, 'B') !== false) {
                     echo ' <label><input type="checkbox" name="SOUR_INDI" ', $level1_checked, ' value="1">', I18N::translate('Individual'), '</label>';
                     if (preg_match_all('/(' . WT_REGEX_TAG . ')/', $WT_TREE->getPreference('QUICK_REQUIRED_FACTS'), $matches)) {
                         foreach ($matches[1] as $match) {
                             if (!in_array($match, explode('|', WT_EVENTS_DEAT))) {
                                 echo ' <label><input type="checkbox" name="SOUR_', $match, '" ', $level2_checked, ' value="1">', GedcomTag::getLabel($match), '</label>';
                             }
                         }
                     }
                 }
                 if (strpos($bdm, 'D') !== false) {
                     if (preg_match_all('/(' . WT_REGEX_TAG . ')/', $WT_TREE->getPreference('QUICK_REQUIRED_FACTS'), $matches)) {
                         foreach ($matches[1] as $match) {
                             if (in_array($match, explode('|', WT_EVENTS_DEAT))) {
                                 echo ' <label><input type="checkbox" name="SOUR_', $match, '"', $level2_checked, ' value="1">', GedcomTag::getLabel($match), '</label>';
                             }
                         }
                     }
                 }
                 if (strpos($bdm, 'M') !== false) {
                     echo ' <label><input type="checkbox" name="SOUR_FAM" ', $level1_checked, ' value="1">', I18N::translate('Family'), '</label>';
                     if (preg_match_all('/(' . WT_REGEX_TAG . ')/', $WT_TREE->getPreference('QUICK_REQUIRED_FAMFACTS'), $matches)) {
                         foreach ($matches[1] as $match) {
                             echo ' <label><input type="checkbox" name="SOUR_', $match, '"', $level2_checked, ' value="1">', GedcomTag::getLabel($match), '</label>';
                         }
                     }
                 }
             }
             break;
         case 'REPO':
             echo FunctionsPrint::printFindRepositoryLink($element_id), ' ', self::printAddNewRepositoryLink($element_id);
             break;
         case 'NOTE':
             // Shared Notes Icons ========================================
             if ($islink) {
                 // Print regular Shared Note icons ---------------------------
                 echo ' ', FunctionsPrint::printFindNoteLink($element_id, $element_id . '_description'), ' ', self::printAddNewNoteLink($element_id);
                 if ($value) {
                     echo ' ', self::printEditNoteLink($value);
                 }
             }
             break;
         case 'OBJE':
             echo FunctionsPrint::printFindMediaLink($element_id, '1media');
             if (!$value) {
                 echo ' ', self::printAddNewMediaLink($element_id);
                 $value = 'new';
             }
             break;
     }
     echo '<div id="' . $element_id . '_description">';
     // current value
     if ($fact === 'DATE') {
         $date = new Date($value);
         echo $date->display();
     }
     if (($fact === 'ASSO' || $fact === '_ASSO') && $value === '') {
         if ($level === 1) {
             echo '<p class="small text-muted">' . I18N::translate('An associate is another individual who was involved with this individual, such as a friend or an employer.') . '</p>';
         } else {
             echo '<p class="small text-muted">' . I18N::translate('An associate is another individual who was involved with this fact or event, such as a witness or a priest.') . '</p>';
         }
     }
     if ($value && $value !== 'new' && $islink) {
         switch ($fact) {
             case 'ALIA':
             case 'ASSO':
             case '_ASSO':
                 $tmp = Individual::getInstance($value, $WT_TREE);
                 if ($tmp) {
                     echo ' ', $tmp->getFullName();
                 }
                 break;
             case 'SOUR':
                 $tmp = Source::getInstance($value, $WT_TREE);
                 if ($tmp) {
                     echo ' ', $tmp->getFullName();
                 }
                 break;
             case 'NOTE':
                 $tmp = Note::getInstance($value, $WT_TREE);
                 if ($tmp) {
                     echo ' ', $tmp->getFullName();
                 }
                 break;
             case 'OBJE':
                 $tmp = Media::getInstance($value, $WT_TREE);
                 if ($tmp) {
                     echo ' ', $tmp->getFullName();
                 }
                 break;
             case 'REPO':
                 $tmp = Repository::getInstance($value, $WT_TREE);
                 if ($tmp) {
                     echo ' ', $tmp->getFullName();
                 }
                 break;
         }
     }
     // pastable values
     if ($fact === 'FORM' && $upperlevel === 'OBJE') {
         FunctionsPrint::printAutoPasteLink($element_id, Config::fileFormats());
     }
     echo '</div>', $extra, '</td></tr>';
     return $element_id;
 }
コード例 #23
0
ファイル: action.php プロジェクト: josefpavlik/webtrees
                         // Level 1 links
                         $source->deleteFact($fact->getFactId(), true);
                     } elseif (strpos($fact->getGedcom(), ' @' . $target . '@')) {
                         // Level 2-3 links
                         $source->updateFact($fact->getFactId(), preg_replace(array('/\\n2 OBJE @' . $target . '@(\\n[3-9].*)*/', '/\\n3 OBJE @' . $target . '@(\\n[4-9].*)*/'), '', $fact->getGedcom()), true);
                     }
                 }
             }
         }
     } else {
         http_response_code(406);
     }
     break;
 case 'reject-changes':
     // Reject all the pending changes for a record
     $record = GedcomRecord::getInstance(Filter::post('xref', WT_REGEX_XREF), $WT_TREE);
     if ($record && $record->canEdit() && Auth::isModerator($record->getTree())) {
         FlashMessages::addMessage(I18N::translate('The changes to “%s” have been rejected.', $record->getFullName()));
         FunctionsImport::rejectAllChanges($record);
     } else {
         http_response_code(406);
     }
     break;
 case 'theme':
     // Change the current theme
     $theme = Filter::post('theme');
     if (Site::getPreference('ALLOW_USER_THEMES') && array_key_exists($theme, Theme::themeNames())) {
         Session::put('theme_id', $theme);
         // Remember our selection
         Auth::user()->setPreference('theme', $theme);
     } else {
コード例 #24
0
 /**
  * Get the current view of a record, allowing for pending changes
  *
  * @param string $xref
  * @param string $type
  *
  * @return string
  */
 public static function getLatestRecord($xref, $type)
 {
     global $WT_TREE;
     switch ($type) {
         case 'INDI':
             return Individual::getInstance($xref, $WT_TREE)->getGedcom();
         case 'FAM':
             return Family::getInstance($xref, $WT_TREE)->getGedcom();
         case 'SOUR':
             return Source::getInstance($xref, $WT_TREE)->getGedcom();
         case 'REPO':
             return Repository::getInstance($xref, $WT_TREE)->getGedcom();
         case 'OBJE':
             return Media::getInstance($xref, $WT_TREE)->getGedcom();
         case 'NOTE':
             return Note::getInstance($xref, $WT_TREE)->getGedcom();
         default:
             return GedcomRecord::getInstance($xref, $WT_TREE)->getGedcom();
     }
 }
コード例 #25
0
 /**
  * Export the database in GEDCOM format
  *
  * @param Tree $tree Which tree to export
  * @param resource $gedout Handle to a writable stream
  * @param string[] $exportOptions Export options are as follows:
  *                                'privatize':    which Privacy rules apply? (none, visitor, user, manager)
  *                                'toANSI':       should the output be produced in ISO-8859-1 instead of UTF-8? (yes, no)
  *                                'path':         what constant should prefix all media file paths? (eg: media/  or c:\my pictures\my family
  *                                'slashes':      what folder separators apply to media file paths? (forward, backward)
  */
 public static function exportGedcom(Tree $tree, $gedout, $exportOptions)
 {
     switch ($exportOptions['privatize']) {
         case 'gedadmin':
             $access_level = Auth::PRIV_NONE;
             break;
         case 'user':
             $access_level = Auth::PRIV_USER;
             break;
         case 'visitor':
             $access_level = Auth::PRIV_PRIVATE;
             break;
         case 'none':
             $access_level = Auth::PRIV_HIDE;
             break;
     }
     $head = self::gedcomHeader($tree);
     if ($exportOptions['toANSI'] == 'yes') {
         $head = str_replace('UTF-8', 'ANSI', $head);
         $head = utf8_decode($head);
     }
     $head = self::reformatRecord($head);
     fwrite($gedout, $head);
     // Buffer the output. Lots of small fwrite() calls can be very slow when writing large gedcoms.
     $buffer = '';
     // Generate the OBJE/SOUR/REPO/NOTE records first, as their privacy calcualations involve
     // database queries, and we wish to avoid large gaps between queries due to MySQL connection timeouts.
     $tmp_gedcom = '';
     $rows = Database::prepare("SELECT m_id AS xref, m_gedcom AS gedcom" . " FROM `##media` WHERE m_file = :tree_id ORDER BY m_id")->execute(array('tree_id' => $tree->getTreeId()))->fetchAll();
     foreach ($rows as $row) {
         $rec = Media::getInstance($row->xref, $tree, $row->gedcom)->privatizeGedcom($access_level);
         $rec = self::convertMediaPath($rec, $exportOptions['path']);
         if ($exportOptions['toANSI'] === 'yes') {
             $rec = utf8_decode($rec);
         }
         $tmp_gedcom .= self::reformatRecord($rec);
     }
     $rows = Database::prepare("SELECT s_id AS xref, s_file AS gedcom_id, s_gedcom AS gedcom" . " FROM `##sources` WHERE s_file = :tree_id ORDER BY s_id")->execute(array('tree_id' => $tree->getTreeId()))->fetchAll();
     foreach ($rows as $row) {
         $rec = Source::getInstance($row->xref, $tree, $row->gedcom)->privatizeGedcom($access_level);
         if ($exportOptions['toANSI'] === 'yes') {
             $rec = utf8_decode($rec);
         }
         $tmp_gedcom .= self::reformatRecord($rec);
     }
     $rows = Database::prepare("SELECT o_type AS type, o_id AS xref, o_gedcom AS gedcom" . " FROM `##other` WHERE o_file = :tree_id AND o_type NOT IN ('HEAD', 'TRLR') ORDER BY o_id")->execute(array('tree_id' => $tree->getTreeId()))->fetchAll();
     foreach ($rows as $row) {
         switch ($row->type) {
             case 'NOTE':
                 $record = Note::getInstance($row->xref, $tree, $row->gedcom);
                 break;
             case 'REPO':
                 $record = Repository::getInstance($row->xref, $tree, $row->gedcom);
                 break;
             default:
                 $record = GedcomRecord::getInstance($row->xref, $tree, $row->gedcom);
                 break;
         }
         $rec = $record->privatizeGedcom($access_level);
         if ($exportOptions['toANSI'] === 'yes') {
             $rec = utf8_decode($rec);
         }
         $tmp_gedcom .= self::reformatRecord($rec);
     }
     $rows = Database::prepare("SELECT i_id AS xref, i_gedcom AS gedcom" . " FROM `##individuals` WHERE i_file = :tree_id ORDER BY i_id")->execute(array('tree_id' => $tree->getTreeId()))->fetchAll();
     foreach ($rows as $row) {
         $rec = Individual::getInstance($row->xref, $tree, $row->gedcom)->privatizeGedcom($access_level);
         if ($exportOptions['toANSI'] === 'yes') {
             $rec = utf8_decode($rec);
         }
         $buffer .= self::reformatRecord($rec);
         if (strlen($buffer) > 65536) {
             fwrite($gedout, $buffer);
             $buffer = '';
         }
     }
     $rows = Database::prepare("SELECT f_id AS xref, f_gedcom AS gedcom" . " FROM `##families` WHERE f_file = :tree_id ORDER BY f_id")->execute(array('tree_id' => $tree->getTreeId()))->fetchAll();
     foreach ($rows as $row) {
         $rec = Family::getInstance($row->xref, $tree, $row->gedcom)->privatizeGedcom($access_level);
         if ($exportOptions['toANSI'] === 'yes') {
             $rec = utf8_decode($rec);
         }
         $buffer .= self::reformatRecord($rec);
         if (strlen($buffer) > 65536) {
             fwrite($gedout, $buffer);
             $buffer = '';
         }
     }
     fwrite($gedout, $buffer);
     fwrite($gedout, $tmp_gedcom);
     fwrite($gedout, '0 TRLR' . WT_EOL);
 }
コード例 #26
0
ファイル: AbstractTheme.php プロジェクト: tronsmit/webtrees
 /**
  * Favorites menu.
  *
  * @return Menu|null
  */
 protected function menuFavorites()
 {
     global $controller;
     $show_user_favorites = $this->tree && Module::getModuleByName('user_favorites') && Auth::check();
     $show_tree_favorites = $this->tree && Module::getModuleByName('gedcom_favorites');
     if ($show_user_favorites && $show_tree_favorites) {
         $favorites = array_merge(FamilyTreeFavoritesModule::getFavorites($this->tree->getTreeId()), UserFavoritesModule::getFavorites(Auth::id()));
     } elseif ($show_user_favorites) {
         $favorites = UserFavoritesModule::getFavorites(Auth::id());
     } elseif ($show_tree_favorites) {
         $favorites = FamilyTreeFavoritesModule::getFavorites($this->tree->getTreeId());
     } else {
         $favorites = array();
     }
     $submenus = array();
     $records = array();
     foreach ($favorites as $favorite) {
         switch ($favorite['type']) {
             case 'URL':
                 $submenus[] = new Menu($favorite['title'], $favorite['url']);
                 break;
             case 'INDI':
             case 'FAM':
             case 'SOUR':
             case 'OBJE':
             case 'NOTE':
                 $record = GedcomRecord::getInstance($favorite['gid'], $this->tree);
                 if ($record && $record->canShowName()) {
                     $submenus[] = new Menu($record->getFullName(), $record->getHtmlUrl());
                     $records[] = $record;
                 }
                 break;
         }
     }
     if ($show_user_favorites && isset($controller->record) && $controller->record instanceof GedcomRecord && !in_array($controller->record, $records)) {
         $submenus[] = new Menu(I18N::translate('Add to favorites'), '#', '', array('onclick' => 'jQuery.post("module.php?mod=user_favorites&mod_action=menu-add-favorite", {xref:"' . $controller->record->getXref() . '"},function(){location.reload();})'));
     }
     if (empty($submenus)) {
         return null;
     } else {
         return new Menu(I18N::translate('Favorites'), '#', 'menu-favorites', array(), $submenus);
     }
 }
コード例 #27
0
ファイル: edit_interface.php プロジェクト: jflash/webtrees
	<?php 
        break;
        ////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////
    case 'update':
        // Update a fact
        $xref = Filter::post('xref', WT_REGEX_XREF);
        $fact_id = Filter::post('fact_id');
        $keep_chan = Filter::postBool('keep_chan');
        if (!Filter::checkCsrf()) {
            $prev_action = Filter::post('prev_action', 'add|edit|addname|editname');
            $fact_type = Filter::post('fact_type', WT_REGEX_TAG);
            header('Location: ' . WT_BASE_URL . WT_SCRIPT_NAME . '?action=' . $prev_action . '&xref=' . $xref . '&fact_id=' . $fact_id . '&fact=' . $fact_type);
            return;
        }
        $record = GedcomRecord::getInstance($xref, $WT_TREE);
        check_record_access($record);
        // Arrays for each GEDCOM line
        $glevels = Filter::postArray('glevels', '[0-9]');
        $tag = Filter::postArray('tag', WT_REGEX_TAG);
        $text = Filter::postArray('text');
        $islink = Filter::postArray('islink', '[01]');
        $controller->setPageTitle(I18N::translate('Edit'))->pageHeader();
        // If the fact has a DATE or PLAC, then delete any value of Y
        if ($text[0] === 'Y') {
            for ($n = 1; $n < count($tag); ++$n) {
                if ($glevels[$n] == 2 && ($tag[$n] === 'DATE' || $tag[$n] === 'PLAC') && $text[$n]) {
                    $text[0] = '';
                    break;
                }
            }
コード例 #28
0
$formats = array('' => I18N::translate('none'), 'markdown' => I18N::translate('markdown'));
$source_types = array(0 => I18N::translate('none'), 1 => I18N::translate('facts'), 2 => I18N::translate('records'));
$no_yes = array(0 => I18N::translate('no'), 1 => I18N::translate('yes'));
$PRIVACY_CONSTANTS = array('none' => I18N::translate('Show to visitors'), 'privacy' => I18N::translate('Show to members'), 'confidential' => I18N::translate('Show to managers'), 'hidden' => I18N::translate('Hide from everyone'));
$privacy = array(Auth::PRIV_PRIVATE => I18N::translate('Show to visitors'), Auth::PRIV_USER => I18N::translate('Show to members'), Auth::PRIV_NONE => I18N::translate('Show to managers'), Auth::PRIV_HIDE => I18N::translate('Hide from everyone'));
$tags = array_unique(array_merge(explode(',', $WT_TREE->getPreference('INDI_FACTS_ADD')), explode(',', $WT_TREE->getPreference('INDI_FACTS_UNIQUE')), explode(',', $WT_TREE->getPreference('FAM_FACTS_ADD')), explode(',', $WT_TREE->getPreference('FAM_FACTS_UNIQUE')), explode(',', $WT_TREE->getPreference('NOTE_FACTS_ADD')), explode(',', $WT_TREE->getPreference('NOTE_FACTS_UNIQUE')), explode(',', $WT_TREE->getPreference('SOUR_FACTS_ADD')), explode(',', $WT_TREE->getPreference('SOUR_FACTS_UNIQUE')), explode(',', $WT_TREE->getPreference('REPO_FACTS_ADD')), explode(',', $WT_TREE->getPreference('REPO_FACTS_UNIQUE')), array('SOUR', 'REPO', 'OBJE', '_PRIM', 'NOTE', 'SUBM', 'SUBN', '_UID', 'CHAN')));
$all_tags = array();
foreach ($tags as $tag) {
    if ($tag) {
        $all_tags[$tag] = GedcomTag::getLabel($tag);
    }
}
uasort($all_tags, '\\Fisharebest\\Webtrees\\I18N::strcasecmp');
$resns = Database::prepare("SELECT default_resn_id, tag_type, xref, resn" . " FROM `##default_resn`" . " LEFT JOIN `##name` ON (gedcom_id=n_file AND xref=n_id AND n_num=0)" . " WHERE gedcom_id=?" . " ORDER BY xref IS NULL, n_sort, xref, tag_type")->execute(array($WT_TREE->getTreeId()))->fetchAll();
foreach ($resns as $resn) {
    $resn->record = GedcomRecord::getInstance($resn->xref, $WT_TREE);
    if ($resn->tag_type) {
        $resn->tag_label = GedcomTag::getLabel($resn->tag_type);
    } else {
        $resn->tag_label = '';
    }
}
usort($resns, function (\stdClass $x, \stdClass $y) {
    return I18N::strcasecmp($x->tag_label, $y->tag_label);
});
// We have two fields in one
$CALENDAR_FORMATS = explode('_and_', $WT_TREE->getPreference('CALENDAR_FORMAT') . '_and_');
// Split into separate fields
$relatives_events = explode(',', $WT_TREE->getPreference('SHOW_RELATIVES_EVENTS'));
switch (Filter::post('action')) {
    case 'privacy':
コード例 #29
0
ファイル: SearchController.php プロジェクト: bmhm/webtrees
 /**
  * Startup activity
  */
 public function __construct()
 {
     global $WT_TREE;
     parent::__construct();
     // $action comes from GET (search) or POST (replace)
     if (Filter::post('action')) {
         $this->action = Filter::post('action', 'replace', 'general');
         $this->query = Filter::post('query');
         $this->replace = Filter::post('replace');
         $this->replaceNames = Filter::post('replaceNames', 'checked', '');
         $this->replacePlaces = Filter::post('replacePlaces', 'checked', '');
         $this->replacePlacesWord = Filter::post('replacePlacesWord', 'checked', '');
         $this->replaceAll = Filter::post('replaceAll', 'checked', '');
     } else {
         $this->action = Filter::get('action', 'advanced|general|soundex|replace|header', 'general');
         $this->query = Filter::get('query');
         $this->replace = Filter::get('replace');
         $this->replaceNames = Filter::get('replaceNames', 'checked', '');
         $this->replacePlaces = Filter::get('replacePlaces', 'checked', '');
         $this->replacePlacesWord = Filter::get('replacePlacesWord', 'checked', '');
         $this->replaceAll = Filter::get('replaceAll', 'checked', '');
     }
     // Only editors can use search/replace
     if ($this->action === 'replace' && !Auth::isEditor($WT_TREE)) {
         $this->action = 'general';
     }
     $this->srindi = Filter::get('srindi', 'checked', '');
     $this->srfams = Filter::get('srfams', 'checked', '');
     $this->srsour = Filter::get('srsour', 'checked', '');
     $this->srnote = Filter::get('srnote', 'checked', '');
     $this->soundex = Filter::get('soundex', 'DaitchM|Russell', 'DaitchM');
     $this->showasso = Filter::get('showasso');
     $this->firstname = Filter::get('firstname');
     $this->lastname = Filter::get('lastname');
     $this->place = Filter::get('place');
     $this->year = Filter::get('year');
     // If no record types specified, search individuals
     if (!$this->srfams && !$this->srsour && !$this->srnote) {
         $this->srindi = 'checked';
     }
     // If no replace types specifiied, replace full records
     if (!$this->replaceNames && !$this->replacePlaces && !$this->replacePlacesWord) {
         $this->replaceAll = 'checked';
     }
     // Trees to search
     if (Site::getPreference('ALLOW_CHANGE_GEDCOM')) {
         foreach (Tree::getAll() as $search_tree) {
             if (Filter::get('tree_' . $search_tree->getTreeId())) {
                 $this->search_trees[] = $search_tree;
             }
         }
         if (!$this->search_trees) {
             $this->search_trees[] = $WT_TREE;
         }
     } else {
         $this->search_trees[] = $WT_TREE;
     }
     // If we want to show associated persons, build the list
     switch ($this->action) {
         case 'header':
             // We can type in an XREF into the header search, and jump straight to it.
             // Otherwise, the header search is the same as the general search
             if (preg_match('/' . WT_REGEX_XREF . '/', $this->query)) {
                 $record = GedcomRecord::getInstance($this->query, $WT_TREE);
                 if ($record && $record->canShowName()) {
                     header('Location: ' . WT_BASE_URL . $record->getRawUrl());
                     exit;
                 }
             }
             $this->action = 'general';
             $this->srindi = 'checked';
             $this->srfams = 'checked';
             $this->srsour = 'checked';
             $this->srnote = 'checked';
             $this->setPageTitle(I18N::translate('General search'));
             $this->generalSearch();
             break;
         case 'general':
             $this->setPageTitle(I18N::translate('General search'));
             $this->generalSearch();
             break;
         case 'soundex':
             // Create a dummy search query to use as a title to the results list
             $this->query = trim($this->firstname . ' ' . $this->lastname . ' ' . $this->place);
             $this->setPageTitle(I18N::translate('Phonetic search'));
             $this->soundexSearch();
             break;
         case 'replace':
             $this->setPageTitle(I18N::translate('Search and replace'));
             $this->search_trees = array($WT_TREE);
             $this->srindi = 'checked';
             $this->srfams = 'checked';
             $this->srsour = 'checked';
             $this->srnote = 'checked';
             if (Filter::post('query')) {
                 $this->searchAndReplace($WT_TREE);
                 header('Location: ' . WT_BASE_URL . WT_SCRIPT_NAME . '?action=replace&query=' . Filter::escapeUrl($this->query) . '&replace=' . Filter::escapeUrl($this->replace) . '&replaceAll=' . $this->replaceAll . '&replaceNames=' . $this->replaceNames . '&replacePlaces=' . $this->replacePlaces . '&replacePlacesWord=' . $this->replacePlacesWord);
                 exit;
             }
     }
 }
コード例 #30
0
 /**
  * Find records that have changed since a given julian day
  *
  * @param Tree $tree Changes for which tree
  * @param int  $jd   Julian day
  *
  * @return GedcomRecord[] List of records with changes
  */
 private function getRecentChanges(Tree $tree, $jd)
 {
     $sql = "SELECT d_gid FROM `##dates`" . " WHERE d_fact='CHAN' AND d_julianday1 >= :jd AND d_file = :tree_id";
     $vars = array('jd' => $jd, 'tree_id' => $tree->getTreeId());
     $xrefs = Database::prepare($sql)->execute($vars)->fetchOneColumn();
     $records = array();
     foreach ($xrefs as $xref) {
         $record = GedcomRecord::getInstance($xref, $tree);
         if ($record->canShow()) {
             $records[] = $record;
         }
     }
     return $records;
 }