예제 #1
0
 /**
  * Create resources for the colors theme.
  */
 public function hookAfterInit()
 {
     $this->palettes = array('aquamarine' => I18N::translate('Aqua Marine'), 'ash' => I18N::translate('Ash'), 'belgianchocolate' => I18N::translate('Belgian Chocolate'), 'bluelagoon' => I18N::translate('Blue Lagoon'), 'bluemarine' => I18N::translate('Blue Marine'), 'coffeeandcream' => I18N::translate('Coffee and Cream'), 'coldday' => I18N::translate('Cold Day'), 'greenbeam' => I18N::translate('Green Beam'), 'mediterranio' => I18N::translate('Mediterranio'), 'mercury' => I18N::translate('Mercury'), 'nocturnal' => I18N::translate('Nocturnal'), 'olivia' => I18N::translate('Olivia'), 'pinkplastic' => I18N::translate('Pink Plastic'), 'sage' => I18N::translate('Sage'), 'shinytomato' => I18N::translate('Shiny Tomato'), 'tealtop' => I18N::translate('Teal Top'));
     uasort($this->palettes, '\\Fisharebest\\Webtrees\\I18N::strcasecmp');
     // If we've selected a new palette, and we are logged in, set this value as a default.
     if (isset($_GET['themecolor']) && array_key_exists($_GET['themecolor'], $this->palettes)) {
         // Request to change color
         $this->palette = $_GET['themecolor'];
         Auth::user()->setPreference('themecolor', $this->palette);
         if (Auth::isAdmin()) {
             Site::setPreference('DEFAULT_COLOR_PALETTE', $this->palette);
         }
         unset($_GET['themecolor']);
         // Rember that we have selected a value
         Session::put('subColor', $this->palette);
     }
     // If we are logged in, use our preference
     $this->palette = Auth::user()->getPreference('themecolor');
     // If not logged in or no preference, use one we selected earlier in the session?
     if (!$this->palette) {
         $this->palette = Session::get('subColor');
     }
     // We haven't selected one this session? Use the site default
     if (!$this->palette) {
         $this->palette = Site::getPreference('DEFAULT_COLOR_PALETTE');
     }
     // Make sure our selected palette actually exists
     if (!array_key_exists($this->palette, $this->palettes)) {
         $this->palette = 'ash';
     }
 }
예제 #2
0
 /**
  * Default buttons are update and update_all
  *
  * @param string $xref
  *
  * @return string[]
  */
 public function getActionButtons($xref)
 {
     if (Auth::user()->getPreference('auto_accept')) {
         return array(BatchUpdateModule::createSubmitButton(I18N::translate('Update'), $xref, 'update'), BatchUpdateModule::createSubmitButton(I18N::translate('Update all'), $xref, 'update_all'));
     } else {
         return array(BatchUpdateModule::createSubmitButton(I18N::translate('Update'), $xref, 'update'));
     }
 }
 /**
  * Return a menu item for this chart.
  *
  * @param Individual $individual
  *
  * @return Menu|null
  */
 public function getChartMenu(Individual $individual)
 {
     $tree = $individual->getTree();
     $gedcomid = $tree->getUserPreference(Auth::user(), 'gedcomid');
     if ($gedcomid) {
         return new Menu(I18N::translate('Relationship to me'), 'relationship.php?pid1=' . $gedcomid . '&pid2=' . $individual->getXref() . '&ged=' . $tree->getNameUrl(), 'menu-chart-relationship', array('rel' => 'nofollow'));
     } else {
         return new Menu(I18N::translate('Relationships'), 'relationship.php?pid1=' . $individual->getXref() . '&ged=' . $tree->getNameUrl(), 'menu-chart-relationship', array('rel' => 'nofollow'));
     }
 }
예제 #4
0
 /**
  * {@inheritDoc}
  * @see \MyArtJaub\Webtrees\Mvc\Controller\MvcController::__construct(AbstractModule $module)
  */
 public function __construct(AbstractModule $module)
 {
     global $WT_TREE;
     parent::__construct($module);
     $this->sosa_provider = new SosaProvider($WT_TREE, Auth::user());
     $this->generation = Filter::getInteger('gen');
     $this->view_bag = new ViewBag();
     $this->view_bag->set('generation', $this->generation);
     $this->view_bag->set('max_gen', $this->sosa_provider->getLastGeneration());
     $this->view_bag->set('is_setup', $this->sosa_provider->isSetup() && $this->view_bag->get('max_gen', 0) > 0);
 }
예제 #5
0
 /**
  * Create a branches list controller
  */
 public function __construct()
 {
     global $WT_TREE;
     parent::__construct();
     $this->surname = Filter::get('surname');
     $this->soundex_std = Filter::getBool('soundex_std');
     $this->soundex_dm = Filter::getBool('soundex_dm');
     if ($this->surname) {
         $this->setPageTitle(I18N::translate('Branches of the %s family', Filter::escapeHtml($this->surname)));
         $this->loadIndividuals();
         $self = Individual::getInstance($WT_TREE->getUserPreference(Auth::user(), 'gedcomid'), $WT_TREE);
         if ($self) {
             $this->loadAncestors($self, 1);
         }
     } else {
         $this->setPageTitle(I18N::translate('Branches'));
     }
 }
예제 #6
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 $WT_TREE;
     $id = $this->getName() . $block_id;
     $class = $this->getName() . '_block';
     $title = '<span dir="auto">' . I18N::translate('Welcome %s', Auth::user()->getRealNameHtml()) . '</span>';
     $content = '<table><tr>';
     $content .= '<td><a href="edituser.php"><i class="icon-mypage"></i><br>' . I18N::translate('My account') . '</a></td>';
     $gedcomid = $WT_TREE->getUserPreference(Auth::user(), 'gedcomid');
     if ($gedcomid) {
         $content .= '<td><a href="pedigree.php?rootid=' . $gedcomid . '&amp;ged=' . $WT_TREE->getNameUrl() . '"><i class="icon-pedigree"></i><br>' . I18N::translate('My pedigree') . '</a></td>';
         $content .= '<td><a href="individual.php?pid=' . $gedcomid . '&amp;ged=' . $WT_TREE->getNameUrl() . '"><i class="icon-indis"></i><br>' . I18N::translate('My individual record') . '</a></td>';
     }
     $content .= '</tr></table>';
     if ($template) {
         return Theme::theme()->formatBlock($id, $title, $class, $content);
     } else {
         return $content;
     }
 }
예제 #7
0
    /**
     * Main entry point
     *
     * @return string
     */
    private function main()
    {
        global $WT_TREE;
        $this->plugins = $this->getPluginList();
        // List of available plugins
        $this->plugin = Filter::get('plugin');
        // User parameters
        $this->xref = Filter::get('xref', WT_REGEX_XREF);
        $this->action = Filter::get('action');
        $this->data = Filter::get('data');
        // Don't do any processing until a plugin is chosen.
        if ($this->plugin && array_key_exists($this->plugin, $this->plugins)) {
            $this->PLUGIN = new $this->plugin();
            $this->PLUGIN->getOptions();
            $this->getAllXrefs();
            switch ($this->action) {
                case 'update':
                    $record = self::getLatestRecord($this->xref, $this->all_xrefs[$this->xref]);
                    if ($this->PLUGIN->doesRecordNeedUpdate($this->xref, $record)) {
                        $newrecord = $this->PLUGIN->updateRecord($this->xref, $record);
                        if ($newrecord != $record) {
                            if ($newrecord) {
                                GedcomRecord::getInstance($this->xref, $WT_TREE)->updateRecord($newrecord, $this->PLUGIN->chan);
                            } else {
                                GedcomRecord::getInstance($this->xref, $WT_TREE)->deleteRecord();
                            }
                        }
                    }
                    $this->xref = $this->findNextXref($this->xref);
                    break;
                case 'update_all':
                    foreach ($this->all_xrefs as $xref => $type) {
                        $record = self::getLatestRecord($xref, $type);
                        if ($this->PLUGIN->doesRecordNeedUpdate($xref, $record)) {
                            $newrecord = $this->PLUGIN->updateRecord($xref, $record);
                            if ($newrecord != $record) {
                                if ($newrecord) {
                                    GedcomRecord::getInstance($xref, $WT_TREE)->updateRecord($newrecord, $this->PLUGIN->chan);
                                } else {
                                    GedcomRecord::getInstance($xref, $WT_TREE)->deleteRecord();
                                }
                            }
                        }
                    }
                    $this->xref = '';
                    break;
            }
            // Make sure that our requested record really does need updating.
            // It may have been updated in another session, or may not have
            // been specified at all.
            if (array_key_exists($this->xref, $this->all_xrefs) && $this->PLUGIN->doesRecordNeedUpdate($this->xref, self::getLatestRecord($this->xref, $this->all_xrefs[$this->xref]))) {
                $this->curr_xref = $this->xref;
            }
            // The requested record doesn't need updating - find one that does
            if (!$this->curr_xref) {
                $this->curr_xref = $this->findNextXref($this->xref);
            }
            if (!$this->curr_xref) {
                $this->curr_xref = $this->findPrevXref($this->xref);
            }
            // If we've found a record to update, get details and look for the next/prev
            if ($this->curr_xref) {
                $this->prev_xref = $this->findPrevXref($this->curr_xref);
                $this->next_xref = $this->findNextXref($this->curr_xref);
            }
        }
        // HTML common to all pages
        $controller = new PageController();
        $controller->setPageTitle(I18N::translate('Batch update'))->restrictAccess(Auth::isAdmin())->pageHeader();
        echo $this->getJavascript();
        ?>
		<ol class="breadcrumb small">
			<li><a href="admin.php"><?php 
        echo I18N::translate('Control panel');
        ?>
</a></li>
			<li><a href="admin_modules.php"><?php 
        echo I18N::translate('Module administration');
        ?>
</a></li>
			<li class="active"><?php 
        echo $controller->getPageTitle();
        ?>
</li>
		</ol>
		<h2><?php 
        echo $controller->getPageTitle();
        ?>
</h2>
		
		<form id="batch_update_form" class="form-horizontal" action="module.php" method="get">
			<input type="hidden" name="mod" value="batch_update">
			<input type="hidden" name="mod_action" value="admin_batch_update">
			<input type="hidden" name="xref"   value="' . $this->xref . '">
			<input type="hidden" name="action" value=""><?php 
        // will be set by javascript for next update
        ?>
			<input type="hidden" name="data"   value=""><?php 
        // will be set by javascript for next update
        ?>
			<div class="form-group">
				<label class="control-label col-sm-3"><?php 
        echo I18N::translate('Family tree');
        ?>
</label>
				<div class="col-sm-9">
		<?php 
        echo FunctionsEdit::selectEditControl('ged', Tree::getNameList(), '', $WT_TREE->getName(), 'class="form-control" onchange="reset_reload();"');
        ?>
				</div>
			</div>
			<div class="form-group">
				<label class="control-label col-sm-3"><?php 
        echo I18N::translate('Batch update');
        ?>
</label>
				<div class="col-sm-9">
					<select class="form-control" name="plugin" onchange="reset_reload();">
						<?php 
        if (!$this->plugin) {
            ?>
							<option value="" selected></option>
						<?php 
        }
        ?>
						<?php 
        foreach ($this->plugins as $class => $plugin) {
            ?>
							<option value="<?php 
            echo $class;
            ?>
" <?php 
            echo $this->plugin == $class ? 'selected' : '';
            ?>
><?php 
            echo $plugin->getName();
            ?>
</option>
					<?php 
        }
        ?>
					</select>
					<?php 
        if ($this->PLUGIN) {
            ?>
						<p class="small text-muted"><?php 
            echo $this->PLUGIN->getDescription();
            ?>
</p>
		<?php 
        }
        ?>
				</div>
			</div>

				<?php 
        if (!Auth::user()->getPreference('auto_accept')) {
            ?>
				<div class="alert alert-danger">
				<?php 
            echo I18N::translate('Your user account does not have “automatically approve changes” enabled.  You will only be able to change one record at a time.');
            ?>
				</div>
			<?php 
        }
        ?>

			<?php 
        // If a plugin is selected, display the details
        ?>
			<?php 
        if ($this->PLUGIN) {
            ?>
				<?php 
            echo $this->PLUGIN->getOptionsForm();
            ?>
				<?php 
            if (substr($this->action, -4) == '_all') {
                ?>
					<?php 
                // Reset - otherwise we might "undo all changes", which refreshes the
                ?>
					<?php 
                // page, which makes them all again!
                ?>
					<script>reset_reload();</script>
			<?php 
            } else {
                ?>
					<hr>
					<div id="batch_update2" class="col-sm-12">
						<?php 
                if ($this->curr_xref) {
                    ?>
							<?php 
                    // Create an object, so we can get the latest version of the name.
                    ?>
								<?php 
                    $this->record = GedcomRecord::getInstance($this->curr_xref, $WT_TREE);
                    ?>
			
							<div class="form-group">
								<?php 
                    echo self::createSubmitButton(I18N::translate('previous'), $this->prev_xref);
                    ?>
					<?php 
                    echo self::createSubmitButton(I18N::translate('next'), $this->next_xref);
                    ?>
							</div>
							<div class="form-group">
								<a class="lead" href="<?php 
                    echo $this->record->getHtmlUrl();
                    ?>
"><?php 
                    echo $this->record->getFullName();
                    ?>
</a>
					<?php 
                    echo $this->PLUGIN->getActionPreview($this->record);
                    ?>
							</div>
							<div class="form-group">
							<?php 
                    echo implode(' ', $this->PLUGIN->getActionButtons($this->curr_xref, $this->record));
                    ?>
							</div>
						<?php 
                } else {
                    ?>
							<div class="alert alert-info"><?php 
                    echo I18N::translate('Nothing found.');
                    ?>
</div>
					<?php 
                }
                ?>
					</div>
				<?php 
            }
            ?>
		<?php 
        }
        ?>
		</form>
		<?php 
    }
예제 #8
0
 /**
  * Constructor for SosaStatsController
  * @param AbstractModule $module
  */
 public function __construct(AbstractModule $module)
 {
     global $WT_TREE;
     parent::__construct($module);
     $this->sosa_provider = new SosaProvider($WT_TREE, Auth::user());
 }
예제 #9
0
 /**
  * For relationship privacy calculations - is this individual a close relative?
  *
  * @param Individual $target
  * @param int        $distance
  *
  * @return bool
  */
 private static function isRelated(Individual $target, $distance)
 {
     static $cache = null;
     $user_individual = self::getInstance($target->tree->getUserPreference(Auth::user(), 'gedcomid'), $target->tree);
     if ($user_individual) {
         if (!$cache) {
             $cache = array(0 => array($user_individual), 1 => array());
             foreach ($user_individual->getFacts('FAM[CS]', false, Auth::PRIV_HIDE) as $fact) {
                 $family = $fact->getTarget();
                 if ($family) {
                     $cache[1][] = $family;
                 }
             }
         }
     } else {
         // No individual linked to this account?  Cannot use relationship privacy.
         return true;
     }
     // Double the distance, as we count the INDI-FAM and FAM-INDI links separately
     $distance *= 2;
     // Consider each path length in turn
     for ($n = 0; $n <= $distance; ++$n) {
         if (array_key_exists($n, $cache)) {
             // We have already calculated all records with this length
             if ($n % 2 == 0 && in_array($target, $cache[$n], true)) {
                 return true;
             }
         } else {
             // Need to calculate these paths
             $cache[$n] = array();
             if ($n % 2 == 0) {
                 // Add FAM->INDI links
                 foreach ($cache[$n - 1] as $family) {
                     foreach ($family->getFacts('HUSB|WIFE|CHIL', false, Auth::PRIV_HIDE) as $fact) {
                         $individual = $fact->getTarget();
                         // Don’t backtrack
                         if ($individual && !in_array($individual, $cache[$n - 2], true)) {
                             $cache[$n][] = $individual;
                         }
                     }
                 }
                 if (in_array($target, $cache[$n], true)) {
                     return true;
                 }
             } else {
                 // Add INDI->FAM links
                 foreach ($cache[$n - 1] as $individual) {
                     foreach ($individual->getFacts('FAM[CS]', false, Auth::PRIV_HIDE) as $fact) {
                         $family = $fact->getTarget();
                         // Don’t backtrack
                         if ($family && !in_array($family, $cache[$n - 2], true)) {
                             $cache[$n][] = $family;
                         }
                     }
                 }
             }
         }
     }
     return false;
 }
예제 #10
0
// Long lists can be broken down by given name
$show_all_firstnames = Filter::get('show_all_firstnames', 'no|yes', 'no');
if ($show_all_firstnames === 'yes') {
    $falpha = '';
} else {
    $falpha = Filter::get('falpha');
    // All first names beginning with this letter
}
$show_marnm = Filter::get('show_marnm', 'no|yes');
switch ($show_marnm) {
    case 'no':
    case 'yes':
        Auth::user()->setPreference(WT_SCRIPT_NAME . '_show_marnm', $show_marnm);
        break;
    default:
        $show_marnm = Auth::user()->getPreference(WT_SCRIPT_NAME . '_show_marnm');
}
// Make sure selections are consistent.
// i.e. can’t specify show_all and surname at the same time.
if ($show_all === 'yes') {
    if ($show_all_firstnames === 'yes') {
        $alpha = '';
        $surname = '';
        $legend = I18N::translate('All');
        $url = WT_SCRIPT_NAME . '?show_all=yes&amp;ged=' . $WT_TREE->getNameUrl();
        $show = 'indi';
    } elseif ($falpha) {
        $alpha = '';
        $surname = '';
        $legend = I18N::translate('All') . ', ' . Filter::escapeHtml($falpha) . '…';
        $url = WT_SCRIPT_NAME . '?show_all=yes&amp;ged=' . $WT_TREE->getNameUrl();
예제 #11
0
    define('WT_LOGIN_URL', WT_BASE_URL . 'login.php');
}
// If there is no current tree and we need one, then redirect somewhere
if (WT_SCRIPT_NAME != 'admin_trees_manage.php' && WT_SCRIPT_NAME != 'admin_pgv_to_wt.php' && WT_SCRIPT_NAME != 'login.php' && WT_SCRIPT_NAME != 'logout.php' && WT_SCRIPT_NAME != 'import.php' && WT_SCRIPT_NAME != 'help_text.php' && WT_SCRIPT_NAME != 'message.php' && WT_SCRIPT_NAME != 'action.php') {
    if (!$WT_TREE || !$WT_TREE->getPreference('imported')) {
        if (Auth::isAdmin()) {
            header('Location: ' . WT_BASE_URL . 'admin_trees_manage.php');
        } else {
            header('Location: ' . WT_LOGIN_URL . '?url=' . rawurlencode(WT_SCRIPT_NAME . (isset($_SERVER['QUERY_STRING']) ? '?' . $_SERVER['QUERY_STRING'] : '')), true, 301);
        }
        exit;
    }
}
// Update the last-login time no more than once a minute
if (WT_TIMESTAMP - Session::get('activity_time') >= 60) {
    Auth::user()->setPreference('sessiontime', WT_TIMESTAMP);
    Session::put('activity_time', WT_TIMESTAMP);
}
// Set the theme
if (substr(WT_SCRIPT_NAME, 0, 5) === 'admin' || WT_SCRIPT_NAME === 'module.php' && substr(Filter::get('mod_action'), 0, 5) === 'admin') {
    // Administration scripts begin with “admin” and use a special administration theme
    Theme::theme(new AdministrationTheme())->init($WT_TREE);
} else {
    // Last theme used?
    $theme_id = Session::get('theme_id');
    // Default for tree
    if (!array_key_exists($theme_id, Theme::themeNames()) && $WT_TREE) {
        $theme_id = $WT_TREE->getPreference('THEME_DIR');
    }
    // Default for site
    if (!array_key_exists($theme_id, Theme::themeNames())) {
예제 #12
0
    if ($filter) {
        echo $filter;
    }
    echo '" autofocus>
	<p><input type="submit" name="search" value="', I18N::translate('Filter'), '" onclick="this.form.subclick.value=this.name">
	<input type="submit" name="all" value="', I18N::translate('Display all'), '" onclick="this.form.subclick.value=this.name">
	</p></form></div>';
}
// Show specialchar and hide the rest
if ($type == 'specialchar') {
    $language_filter = Filter::get('language_filter', null, Auth::user()->getPreference('default_language_filter'));
    $specialchar_languages = SpecialChars::allLanguages();
    if (!array_key_exists($language_filter, $specialchar_languages)) {
        $language_filter = 'en';
    }
    Auth::user()->setPreference('default_language_filter', $language_filter);
    $action = 'filter';
    echo '<div id="find-header">
	<form name="filterspecialchar" method="get" action="find.php">
	<input type="hidden" name="action" value="filter">
	<input type="hidden" name="type" value="specialchar">
	<input type="hidden" name="callback" value="' . $callback . '">
	<p><select id="language_filter" name="language_filter" onchange="submit();">';
    foreach (SpecialChars::allLanguages() as $lanuguage_tag => $language_name) {
        echo '<option value="' . $lanuguage_tag . '" ';
        if ($lanuguage_tag === $language_filter) {
            echo 'selected';
        }
        echo '>', $language_name, '</option>';
    }
    echo '</select>
예제 #13
0
파일: Stats.php 프로젝트: AlexSnet/webtrees
 /**
  * Get the current user's full name.
  *
  * @return string
  */
 public function userFullName()
 {
     return Auth::check() ? Auth::user()->getRealNameHtml() : '';
 }
예제 #14
0
 * GNU General Public License for more details.
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
namespace Fisharebest\Webtrees;

use Fisharebest\Webtrees\Controller\AjaxController;
use Fisharebest\Webtrees\Functions\FunctionsImport;
use PDOException;
define('WT_SCRIPT_NAME', 'import.php');
require './includes/session.php';
// Don't use ged=XX as we want to be able to run without changing the current gedcom.
// This will let us load several gedcoms together, or to edit one while loading another.
$gedcom_id = Filter::getInteger('gedcom_id');
$tree = Tree::findById($gedcom_id);
if (!$tree || !Auth::isManager($tree, Auth::user())) {
    http_response_code(403);
    return;
}
$controller = new AjaxController();
$controller->pageHeader();
// Don't allow the user to cancel the request.  We do not want to be left
// with an incomplete transaction.
ignore_user_abort(true);
// Run in a transaction
Database::beginTransaction();
// Only allow one process to import each gedcom at a time
Database::prepare("SELECT * FROM `##gedcom_chunk` WHERE gedcom_id=? FOR UPDATE")->execute(array($gedcom_id));
// What is the current import status?
$row = Database::prepare("SELECT" . " SUM(IF(imported, LENGTH(chunk_data), 0)) AS import_offset," . " SUM(LENGTH(chunk_data))                  AS import_total" . " FROM `##gedcom_chunk` WHERE gedcom_id=?")->execute(array($gedcom_id))->fetchOneRow();
if ($row->import_offset == $row->import_total) {
예제 #15
0
                        }
                    }
                }
            }
        } 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 {
            // Request for a non-existant theme.
            http_response_code(406);
        }
        break;
}
예제 #16
0
foreach ($facts1 as $id1 => $fact1) {
    foreach ($facts2 as $id2 => $fact2) {
        if ($fact1->getFactId() === $fact2->getFactId()) {
            $facts[] = $fact1;
            unset($facts1[$id1]);
            unset($facts2[$id2]);
        }
    }
}
if ($rec1 && $rec2 && $rec1->getXref() !== $rec2->getXref() && $rec1::RECORD_TYPE === $rec2::RECORD_TYPE && Filter::post('action') === 'merge' && Filter::checkCsrf()) {
    // Use the XREF of the record.
    $gid1 = $rec1->getXref();
    $gid2 = $rec2->getXref();
    $ids = FunctionsDb::fetchAllLinks($gid2, $WT_TREE->getTreeId());
    // If we are not auto-accepting, then we can show a link to the pending deletion
    if (Auth::user()->getPreference('auto_accept')) {
        $record2_name = $rec2->getFullName();
    } else {
        $record2_name = '<a class="alert-link" href="' . $rec2->getHtmlUrl() . '">' . $rec2->getFullName() . '</a>';
    }
    foreach ($ids as $id) {
        $record = GedcomRecord::getInstance($id, $WT_TREE);
        if (!$record->isPendingDeletion()) {
            FlashMessages::addMessage(I18N::translate('The link from “%1$s” to “%2$s” has been updated.', '<a class="alert-link" href="' . $record->getHtmlUrl() . '">' . $record->getFullName() . '</a>', $record2_name), 'info');
            $gedcom = str_replace("@{$gid2}@", "@{$gid1}@", $record->getGedcom());
            $gedcom = preg_replace('/(\\n1.*@.+@.*(?:(?:\\n[2-9].*)*))((?:\\n1.*(?:\\n[2-9].*)*)*\\1)/', '$2', $gedcom);
            $record->updateRecord($gedcom, true);
        }
    }
    // Update any linked user-accounts
    Database::prepare("UPDATE `##user_gedcom_setting`" . " SET setting_value=?" . " WHERE gedcom_id=? AND setting_name='gedcomid' AND setting_value=?")->execute(array($gid2, $WT_TREE->getTreeId(), $gid1));
예제 #17
0
 /**
  * Delete this record
  */
 public function deleteRecord()
 {
     // Create a pending change
     if (!$this->isPendingDeletion()) {
         Database::prepare("INSERT INTO `##change` (gedcom_id, xref, old_gedcom, new_gedcom, user_id) VALUES (?, ?, ?, '', ?)")->execute(array($this->tree->getTreeId(), $this->xref, $this->getGedcom(), Auth::id()));
     }
     // Auto-accept this pending change
     if (Auth::user()->getPreference('auto_accept')) {
         FunctionsImport::acceptAllChanges($this->xref, $this->tree->getTreeId());
     }
     // Clear the cache
     self::$gedcom_record_cache = null;
     self::$pending_record_cache = null;
     Log::addEditLog('Delete: ' . static::RECORD_TYPE . ' ' . $this->xref);
 }
예제 #18
0
// but are submitted in POST so we can have long body text.
$subject = Filter::post('subject', null, Filter::get('subject'));
$body = Filter::post('body');
$from_name = Filter::post('from_name');
$from_email = Filter::post('from_email');
$action = Filter::post('action', 'compose|send', 'compose');
$to = Filter::post('to', null, Filter::get('to'));
$method = Filter::post('method', 'messaging|messaging2|messaging3|mailto|none', Filter::get('method', 'messaging|messaging2|messaging3|mailto|none', 'messaging2'));
$url = Filter::postUrl('url', Filter::getUrl('url'));
$to_user = User::findByUserName($to);
$controller = new SimpleController();
$controller->restrictAccess($to_user || Auth::isAdmin() && ($to === 'all' || $to === 'last_6mo' || $to === 'never_logged'))->setPageTitle(I18N::translate('webtrees message'));
$errors = '';
// Is this message from a member or a visitor?
if (Auth::check()) {
    $from = Auth::user()->getUserName();
} else {
    // Visitors must provide a valid email address
    if ($from_email && (!preg_match("/(.+)@(.+)/", $from_email, $match) || function_exists('checkdnsrr') && checkdnsrr($match[2]) === false)) {
        $errors .= '<p class="ui-state-error">' . I18N::translate('Please enter a valid email address.') . '</p>';
        $action = 'compose';
    }
    // Do not allow anonymous visitors to include links to external sites
    if (preg_match('/(?!' . preg_quote(WT_BASE_URL, '/') . ')(((?:ftp|http|https):\\/\\/)[a-zA-Z0-9.-]+)/', $subject . $body, $match)) {
        $errors .= '<p class="ui-state-error">' . I18N::translate('You are not allowed to send messages that contain external links.') . '</p>' . '<p class="ui-state-highlight">' . I18N::translate('You should delete the “%1$s” from “%2$s” and try again.', $match[2], $match[1]) . '</p>' . Log::addAuthenticationLog('Possible spam message from "' . $from_name . '"/"' . $from_email . '", subject="' . $subject . '", body="' . $body . '"');
        $action = 'compose';
    }
    $from = $from_email;
}
// Ensure the user always visits this page twice - once to compose it and again to send it.
// This makes it harder for spammers.
예제 #19
0
    /**
     * An HTML form to edit block settings
     *
     * @param int $block_id
     */
    public function configureBlock($block_id)
    {
        global $WT_TREE, $controller;
        $PEDIGREE_ROOT_ID = $WT_TREE->getPreference('PEDIGREE_ROOT_ID');
        $gedcomid = $WT_TREE->getUserPreference(Auth::user(), 'gedcomid');
        if (Filter::postBool('save') && Filter::checkCsrf()) {
            $this->setBlockSetting($block_id, 'details', Filter::postBool('details'));
            $this->setBlockSetting($block_id, 'type', Filter::post('type', 'pedigree|descendants|hourglass|treenav', 'pedigree'));
            $this->setBlockSetting($block_id, 'pid', Filter::post('pid', WT_REGEX_XREF));
        }
        $details = $this->getBlockSetting($block_id, 'details', '0');
        $type = $this->getBlockSetting($block_id, 'type', 'pedigree');
        $pid = $this->getBlockSetting($block_id, 'pid', Auth::check() ? $gedcomid ? $gedcomid : $PEDIGREE_ROOT_ID : $PEDIGREE_ROOT_ID);
        $controller->addExternalJavascript(WT_AUTOCOMPLETE_JS_URL)->addInlineJavascript('autocomplete();');
        ?>
		<tr>
			<td class="descriptionbox wrap width33"><?php 
        echo I18N::translate('Chart type');
        ?>
</td>
			<td class="optionbox">
				<?php 
        echo FunctionsEdit::selectEditControl('type', array('pedigree' => I18N::translate('Pedigree'), 'descendants' => I18N::translate('Descendants'), 'hourglass' => I18N::translate('Hourglass chart'), 'treenav' => I18N::translate('Interactive tree')), null, $type);
        ?>
			</td>
		</tr>
		<tr>
			<td class="descriptionbox wrap width33"><?php 
        echo I18N::translate('Show details');
        ?>
</td>
		<td class="optionbox">
			<?php 
        echo FunctionsEdit::editFieldYesNo('details', $details);
        ?>
			</td>
		</tr>
		<tr>
			<td class="descriptionbox wrap width33"><?php 
        echo I18N::translate('Individual');
        ?>
</td>
			<td class="optionbox">
				<input data-autocomplete-type="INDI" type="text" name="pid" id="pid" value="<?php 
        echo $pid;
        ?>
" size="5">
				<?php 
        echo FunctionsPrint::printFindIndividualLink('pid');
        $root = Individual::getInstance($pid, $WT_TREE);
        if ($root) {
            echo ' <span class="list_item">', $root->getFullName(), $root->formatFirstMajorFact(WT_EVENTS_BIRT, 1), '</span>';
        }
        ?>
			</td>
		</tr>
		<?php 
    }
예제 #20
0
파일: login.php 프로젝트: ambled/webtrees
     if (!$user->checkPassword($password)) {
         Log::addAuthenticationLog('Login failed (incorrect password): ' . $username);
         throw new \Exception(I18N::translate('The username or password is incorrect.'));
     }
     if (!$user->getPreference('verified')) {
         Log::addAuthenticationLog('Login failed (not verified by user): ' . $username);
         throw new \Exception(I18N::translate('This account has not been verified.  Please check your email for a verification message.'));
     }
     if (!$user->getPreference('verified_by_admin')) {
         Log::addAuthenticationLog('Login failed (not approved by admin): ' . $username);
         throw new \Exception(I18N::translate('This account has not been approved.  Please wait for an administrator to approve it.'));
     }
     Auth::login($user);
     Log::addAuthenticationLog('Login: '******'/' . Auth::user()->getRealName());
     Session::put('locale', Auth::user()->getPreference('language'));
     Session::put('theme_id', Auth::user()->getPreference('theme'));
     // We're logging in as an administrator
     if (Auth::isAdmin()) {
         // Check for updates
         $latest_version_txt = Functions::fetchLatestVersion();
         if (preg_match('/^[0-9.]+\\|[0-9.]+\\|/', $latest_version_txt)) {
             list($latest_version, $earliest_version, $download_url) = explode('|', $latest_version_txt);
             if (version_compare(WT_VERSION, $latest_version) < 0) {
                 FlashMessages::addMessage(I18N::translate('A new version of webtrees is available.') . ' <a href="admin_site_upgrade.php"><b>' . I18N::translate('Upgrade to webtrees %s.', '<span dir="ltr">' . $latest_version . '</span>') . '</b></a>');
             }
         }
     }
     // Redirect to the target URL
     header('Location: ' . WT_BASE_URL . $url);
     return;
 } catch (\Exception $ex) {
예제 #21
0
        // Total filtered/unfiltered rows
        $recordsFiltered = (int) Database::prepare("SELECT FOUND_ROWS()")->fetchOne();
        $recordsTotal = (int) Database::prepare("SELECT COUNT(*) FROM `##change`")->fetchOne();
        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) . ',
			columns: [
			/* change_id   */ { visible: false },
			/* Timestamp   */ { sort: 0 },
			/* Status      */ { },
			/* Record      */ { },
			/* Old data    */ { sortable: false },
			/* New data    */ { sortable: false },
			/* User        */ { },
			/* Family tree */ { }
			]
		});
		jQuery("#from,#to").parent("div").datetimepicker({
			format: "YYYY-MM-DD",
			minDate: "' . $earliest . '",
			maxDate: "' . $latest . '",
예제 #22
0
 /**
  * A link to the user's individual record.
  *
  * @return Menu|null
  */
 protected function menuMyPedigree()
 {
     $gedcomid = $this->tree->getUserPreference(Auth::user(), 'gedcomid');
     if ($gedcomid && Module::isActiveChart($this->tree, 'pedigree_chart')) {
         $showFull = $this->tree->getPreference('PEDIGREE_FULL_DETAILS') ? 1 : 0;
         $showLayout = $this->tree->getPreference('PEDIGREE_LAYOUT') ? 1 : 0;
         return new Menu(I18N::translate('My pedigree'), 'pedigree.php?' . $this->tree_url . '&amp;rootid=' . $gedcomid . '&amp;show_full=' . $showFull . '&amp;talloffset=' . $showLayout, 'menu-mypedigree');
     } else {
         return null;
     }
 }
예제 #23
0
?>
				<p class="small text-muted">
					<?php 
echo I18N::translate('This checkbox controls your visibility to other users while you’re online. It also controls your ability to see other online users who are configured to be visible.<br><br>When this box is unchecked, you will be completely invisible to others, and you will also not be able to see other online users. When this box is checked, exactly the opposite is true. You will be visible to others, and you will also be able to see others who are configured to be visible.');
?>
				</p>
			</div>
		</div>
		<div id="edituser_submit">
			<input type="submit" value="<?php 
echo I18N::translate('save');
?>
">
		</div>
		<?php 
if (!Auth::user()->getPreference('canadmin')) {
    ?>
		<a href="#" onclick="if (confirm('<?php 
    echo I18N::translate('Are you sure you want to delete “%s”?', Filter::escapeJs(Auth::user()->getUserName()));
    ?>
')) {jQuery('#form_action').val('delete'); document.editform.submit(); }">
			<?php 
    echo I18N::translate('Delete your account');
    ?>
		</a>
		<?php 
}
?>
	</form>
</div>
<?php 
예제 #24
0
            // We're logging in as an administrator
            if (Auth::isAdmin()) {
                // Check for updates
                $latest_version_txt = Functions::fetchLatestVersion();
                if (preg_match('/^[0-9.]+\\|[0-9.]+\\|/', $latest_version_txt)) {
                    list($latest_version, $earliest_version, $download_url) = explode('|', $latest_version_txt);
                    if (version_compare(WT_VERSION, $latest_version) < 0) {
                        FlashMessages::addMessage(I18N::translate('A new version of webtrees is available.') . ' <a href="admin_site_upgrade.php"><b>' . I18N::translate('Upgrade to webtrees %s.', '<span dir="ltr">' . $latest_version . '</span>') . '</b></a>');
                    }
                }
            }
            // If we were on a "home page", redirect to "my page"
            if ($url === '' || strpos($url, 'index.php?ctype=gedcom') === 0) {
                $url = 'index.php?ctype=user';
                // Switch to a tree where we have a genealogy record (or keep to the current/default).
                $tree = Database::prepare("SELECT gedcom_name FROM `##gedcom` JOIN `##user_gedcom_setting` USING (gedcom_id)" . " WHERE setting_name = 'gedcomid' AND user_id = :user_id")->execute(array('user_id' => Auth::user()->getUserId()))->fetchOne();
                $url .= '&ged=' . Filter::escapeUrl($tree);
            }
            // Redirect to the target URL
            header('Location: ' . WT_BASE_URL . $url);
            return;
        } catch (\Exception $ex) {
            $message = $ex->getMessage();
        }
        // No break;
    // No break;
    default:
        $controller->setPageTitle(I18N::translate('Login'))->pageHeader()->addInlineJavascript('
			jQuery("#new_passwd_form").hide();
			jQuery("#passwd_click").click(function() {
				jQuery("#new_passwd_form").slideToggle(100, function() {
예제 #25
0
 /**
  * Create a header for a (newly-created or already-imported) gedcom file.
  *
  * @param Tree $tree
  *
  * @return string
  */
 public static function gedcomHeader(Tree $tree)
 {
     // Default values for a new header
     $HEAD = "0 HEAD";
     $SOUR = "\n1 SOUR " . WT_WEBTREES . "\n2 NAME " . WT_WEBTREES . "\n2 VERS " . WT_VERSION;
     $DEST = "\n1 DEST DISKETTE";
     $DATE = "\n1 DATE " . strtoupper(date("d M Y")) . "\n2 TIME " . date("H:i:s");
     $GEDC = "\n1 GEDC\n2 VERS 5.5.1\n2 FORM Lineage-Linked";
     $CHAR = "\n1 CHAR UTF-8";
     $FILE = "\n1 FILE " . $tree->getName();
     $LANG = "";
     $PLAC = "\n1 PLAC\n2 FORM City, County, State/Province, Country";
     $COPR = "";
     $SUBN = "";
     $SUBM = "\n1 SUBM @SUBM@\n0 @SUBM@ SUBM\n1 NAME " . Auth::user()->getUserName();
     // The SUBM record is mandatory
     // Preserve some values from the original header
     $record = GedcomRecord::getInstance('HEAD', $tree);
     if ($fact = $record->getFirstFact('PLAC')) {
         $PLAC = "\n1 PLAC\n2 FORM " . $fact->getAttribute('FORM');
     }
     if ($fact = $record->getFirstFact('LANG')) {
         $LANG = $fact->getValue();
     }
     if ($fact = $record->getFirstFact('SUBN')) {
         $SUBN = $fact->getValue();
     }
     if ($fact = $record->getFirstFact('COPR')) {
         $COPR = $fact->getValue();
     }
     // Link to actual SUBM/SUBN records, if they exist
     $subn = Database::prepare("SELECT o_id FROM `##other` WHERE o_type=? AND o_file=?")->execute(array('SUBN', $tree->getTreeId()))->fetchOne();
     if ($subn) {
         $SUBN = "\n1 SUBN @{$subn}@";
     }
     $subm = Database::prepare("SELECT o_id FROM `##other` WHERE o_type=? AND o_file=?")->execute(array('SUBM', $tree->getTreeId()))->fetchOne();
     if ($subm) {
         $SUBM = "\n1 SUBM @{$subm}@";
     }
     return $HEAD . $SOUR . $DEST . $DATE . $GEDC . $CHAR . $FILE . $COPR . $LANG . $PLAC . $SUBN . $SUBM . "\n";
 }
예제 #26
0
 /**
  * Get significant information from this page, to allow other pages such as
  * charts and reports to initialise with the same records
  *
  * @return Individual
  */
 public function getSignificantIndividual()
 {
     global $WT_TREE;
     static $individual;
     // Only query the DB once.
     if (!$individual && $WT_TREE->getUserPreference(Auth::user(), 'rootid')) {
         $individual = Individual::getInstance($WT_TREE->getUserPreference(Auth::user(), 'rootid'), $WT_TREE);
     }
     if (!$individual && $WT_TREE->getUserPreference(Auth::user(), 'gedcomid')) {
         $individual = Individual::getInstance($WT_TREE->getUserPreference(Auth::user(), 'gedcomid'), $WT_TREE);
     }
     if (!$individual) {
         $individual = Individual::getInstance($WT_TREE->getPreference('PEDIGREE_ROOT_ID'), $WT_TREE);
     }
     if (!$individual) {
         $individual = Individual::getInstance(Database::prepare("SELECT MIN(i_id) FROM `##individuals` WHERE i_file=?")->execute(array($WT_TREE->getTreeId()))->fetchOne(), $WT_TREE);
     }
     if (!$individual) {
         // always return a record
         $individual = new Individual('I', '0 @I@ INDI', null, $WT_TREE);
     }
     return $individual;
 }
예제 #27
0
        $controller->setPageTitle(I18N::translate('User administration'))->addExternalJavascript(WT_JQUERY_DATATABLES_JS_URL)->addExternalJavascript(WT_DATATABLES_BOOTSTRAP_JS_URL)->addInlineJavascript('
			jQuery(".table-user-list").dataTable({
				' . I18N::datatablesI18N() . ',
				stateSave: true,
				stateDuration: 300,
				processing: true,
				serverSide: true,
				ajax: {
					"url": "' . WT_SCRIPT_NAME . '?action=load_json",
					"type": "POST"
				},
				search: {
					search: "' . Filter::escapeJs(Filter::get('filter')) . '"
				},
				autoWidth: false,
				pageLength: ' . Auth::user()->getPreference('admin_users_page_size', 10) . ',
				sorting: [[2, "asc"]],
				columns: [
					/* details           */ { sortable: false },
					/* user-id           */ { visible: false },
					/* user_name         */ null,
					/* real_name         */ null,
					/* email             */ null,
					/* language          */ null,
					/* registered (sort) */ { visible: false },
					/* registered        */ { dataSort: 7 },
					/* last_login (sort) */ { visible: false },
					/* last_login        */ { dataSort: 9 },
					/* verified          */ null,
					/* approved          */ null
				]
예제 #28
0
 /**
  * Generate both the HTML and PNG components of the fan chart
  *
  * The HTML and PNG components both require the same co-ordinate calculations,
  * so we generate them using the same code, but we send them in separate
  * HTTP requests.
  *
  * @param string $what "png" or "html"
  *
  * @return string
  */
 public function generateFanChart($what)
 {
     $treeid = $this->sosaAncestors($this->generations);
     $fanw = 640 * $this->fan_width / 100;
     $fandeg = 90 * $this->fan_style;
     $html = '';
     $treesize = count($treeid) + 1;
     // generations count
     $gen = log($treesize) / log(2) - 1;
     $sosa = $treesize - 1;
     // fan size
     if ($fandeg == 0) {
         $fandeg = 360;
     }
     $fandeg = min($fandeg, 360);
     $fandeg = max($fandeg, 90);
     $cx = $fanw / 2 - 1;
     // center x
     $cy = $cx;
     // center y
     $rx = $fanw - 1;
     $rw = $fanw / ($gen + 1);
     $fanh = $fanw;
     // fan height
     if ($fandeg == 180) {
         $fanh = round($fanh * ($gen + 1) / ($gen * 2));
     }
     if ($fandeg == 270) {
         $fanh = round($fanh * 0.86);
     }
     $scale = $fanw / 640;
     // image init
     $image = ImageCreate($fanw, $fanh);
     $white = ImageColorAllocate($image, 0xff, 0xff, 0xff);
     ImageFilledRectangle($image, 0, 0, $fanw, $fanh, $white);
     ImageColorTransparent($image, $white);
     $color = ImageColorAllocate($image, hexdec(substr(Theme::theme()->parameter('chart-font-color'), 0, 2)), hexdec(substr(Theme::theme()->parameter('chart-font-color'), 2, 2)), hexdec(substr(Theme::theme()->parameter('chart-font-color'), 4, 2)));
     $bgcolor = ImageColorAllocate($image, hexdec(substr(Theme::theme()->parameter('chart-background-u'), 0, 2)), hexdec(substr(Theme::theme()->parameter('chart-background-u'), 2, 2)), hexdec(substr(Theme::theme()->parameter('chart-background-u'), 4, 2)));
     $bgcolorM = ImageColorAllocate($image, hexdec(substr(Theme::theme()->parameter('chart-background-m'), 0, 2)), hexdec(substr(Theme::theme()->parameter('chart-background-m'), 2, 2)), hexdec(substr(Theme::theme()->parameter('chart-background-m'), 4, 2)));
     $bgcolorF = ImageColorAllocate($image, hexdec(substr(Theme::theme()->parameter('chart-background-f'), 0, 2)), hexdec(substr(Theme::theme()->parameter('chart-background-f'), 2, 2)), hexdec(substr(Theme::theme()->parameter('chart-background-f'), 4, 2)));
     // imagemap
     $imagemap = '<map id="fanmap" name="fanmap">';
     // loop to create fan cells
     while ($gen >= 0) {
         // clean current generation area
         $deg2 = 360 + ($fandeg - 180) / 2;
         $deg1 = $deg2 - $fandeg;
         ImageFilledArc($image, $cx, $cy, $rx, $rx, $deg1, $deg2, $bgcolor, IMG_ARC_PIE);
         $rx -= 3;
         // calculate new angle
         $p2 = pow(2, $gen);
         $angle = $fandeg / $p2;
         $deg2 = 360 + ($fandeg - 180) / 2;
         $deg1 = $deg2 - $angle;
         // special case for rootid cell
         if ($gen == 0) {
             $deg1 = 90;
             $deg2 = 360 + $deg1;
         }
         // draw each cell
         while ($sosa >= $p2) {
             $person = $treeid[$sosa];
             if ($person) {
                 $name = $person->getFullName();
                 $addname = $person->getAddName();
                 $text = I18N::reverseText($name);
                 if ($addname) {
                     $text .= "\n" . I18N::reverseText($addname);
                 }
                 $text .= "\n" . I18N::reverseText($person->getLifeSpan());
                 switch ($person->getSex()) {
                     case 'M':
                         $bg = $bgcolorM;
                         break;
                     case 'F':
                         $bg = $bgcolorF;
                         break;
                     default:
                         $bg = $bgcolor;
                         break;
                 }
                 ImageFilledArc($image, $cx, $cy, $rx, $rx, $deg1, $deg2, $bg, IMG_ARC_PIE);
                 // split and center text by lines
                 $wmax = (int) ($angle * 7 / Theme::theme()->parameter('chart-font-size') * $scale);
                 $wmax = min($wmax, 35 * $scale);
                 if ($gen == 0) {
                     $wmax = min($wmax, 17 * $scale);
                 }
                 $text = $this->splitAlignText($text, $wmax);
                 // text angle
                 $tangle = 270 - ($deg1 + $angle / 2);
                 if ($gen == 0) {
                     $tangle = 0;
                 }
                 // calculate text position
                 $deg = $deg1 + 0.44;
                 if ($deg2 - $deg1 > 40) {
                     $deg = $deg1 + ($deg2 - $deg1) / 11;
                 }
                 if ($deg2 - $deg1 > 80) {
                     $deg = $deg1 + ($deg2 - $deg1) / 7;
                 }
                 if ($deg2 - $deg1 > 140) {
                     $deg = $deg1 + ($deg2 - $deg1) / 4;
                 }
                 if ($gen == 0) {
                     $deg = 180;
                 }
                 $rad = deg2rad($deg);
                 $mr = ($rx - $rw / 4) / 2;
                 if ($gen > 0 && $deg2 - $deg1 > 80) {
                     $mr = $rx / 2;
                 }
                 $tx = $cx + $mr * cos($rad);
                 $ty = $cy - $mr * -sin($rad);
                 if ($sosa == 1) {
                     $ty -= $mr / 2;
                 }
                 // print text
                 ImageTtfText($image, Theme::theme()->parameter('chart-font-size'), $tangle, $tx, $ty, $color, Theme::theme()->parameter('chart-font-name'), $text);
                 $imagemap .= '<area shape="poly" coords="';
                 // plot upper points
                 $mr = $rx / 2;
                 $deg = $deg1;
                 while ($deg <= $deg2) {
                     $rad = deg2rad($deg);
                     $tx = round($cx + $mr * cos($rad));
                     $ty = round($cy - $mr * -sin($rad));
                     $imagemap .= "{$tx},{$ty},";
                     $deg += ($deg2 - $deg1) / 6;
                 }
                 // plot lower points
                 $mr = ($rx - $rw) / 2;
                 $deg = $deg2;
                 while ($deg >= $deg1) {
                     $rad = deg2rad($deg);
                     $tx = round($cx + $mr * cos($rad));
                     $ty = round($cy - $mr * -sin($rad));
                     $imagemap .= "{$tx},{$ty},";
                     $deg -= ($deg2 - $deg1) / 6;
                 }
                 // join first point
                 $mr = $rx / 2;
                 $deg = $deg1;
                 $rad = deg2rad($deg);
                 $tx = round($cx + $mr * cos($rad));
                 $ty = round($cy - $mr * -sin($rad));
                 $imagemap .= "{$tx},{$ty}";
                 // add action url
                 $pid = $person->getXref();
                 $imagemap .= '" href="#' . $pid . '"';
                 $tempURL = 'fanchart.php?rootid=' . $pid . '&amp;generations=' . $this->generations . '&amp;fan_width=' . $this->fan_width . '&amp;fan_style=' . $this->fan_style . '&amp;ged=' . $person->getTree()->getNameUrl();
                 $html .= '<div id="' . $pid . '" class="fan_chart_menu">';
                 $html .= '<div class="person_box"><div class="details1">';
                 $html .= '<a href="' . $person->getHtmlUrl() . '" class="name1">' . $name;
                 if ($addname) {
                     $html .= $addname;
                 }
                 $html .= '</a>';
                 $html .= '<ul class="charts">';
                 $html .= '<li><a href="pedigree.php?rootid=' . $pid . '&amp;ged=' . $person->getTree()->getNameUrl() . '" >' . I18N::translate('Pedigree') . '</a></li>';
                 if (Module::getModuleByName('googlemap')) {
                     $html .= '<li><a href="module.php?mod=googlemap&amp;mod_action=pedigree_map&amp;rootid=' . $pid . '&amp;ged=' . $person->getTree()->getNameUrl() . '">' . I18N::translate('Pedigree map') . '</a></li>';
                 }
                 $gedcomid = $person->getTree()->getUserPreference(Auth::user(), 'gedcomid');
                 if ($gedcomid && $gedcomid != $pid) {
                     $html .= '<li><a href="relationship.php?pid1=' . $gedcomid . '&amp;pid2=' . $pid . '&amp;ged=' . $person->getTree()->getNameUrl() . '">' . I18N::translate('Relationship to me') . '</a></li>';
                 }
                 $html .= '<li><a href="descendancy.php?rootid=' . $pid . '&amp;ged=' . $person->getTree()->getNameUrl() . '" >' . I18N::translate('Descendants') . '</a></li>';
                 $html .= '<li><a href="ancestry.php?rootid=' . $pid . '&amp;ged=' . $person->getTree()->getNameUrl() . '">' . I18N::translate('Ancestors') . '</a></li>';
                 $html .= '<li><a href="compact.php?rootid=' . $pid . '&amp;ged=' . $person->getTree()->getNameUrl() . '">' . I18N::translate('Compact tree') . '</a></li>';
                 $html .= '<li><a href="' . $tempURL . '">' . I18N::translate('Fan chart') . '</a></li>';
                 $html .= '<li><a href="hourglass.php?rootid=' . $pid . '&amp;ged=' . $person->getTree()->getNameUrl() . '">' . I18N::translate('Hourglass chart') . '</a></li>';
                 if (Module::getModuleByName('tree')) {
                     $html .= '<li><a href="module.php?mod=tree&amp;mod_action=treeview&amp;ged=' . $person->getTree()->getNameUrl() . '&amp;rootid=' . $pid . '">' . I18N::translate('Interactive tree') . '</a></li>';
                 }
                 $html .= '</ul>';
                 // spouse(s) and children
                 foreach ($person->getSpouseFamilies() as $family) {
                     $spouse = $family->getSpouse($person);
                     if ($spouse) {
                         $html .= '<a href="' . $spouse->getHtmlUrl() . '" class="name1">' . $spouse->getFullName() . '</a>';
                         $kids = $family->getChildren();
                         if ($kids) {
                             $html .= '<ul class="children">';
                             foreach ($kids as $child) {
                                 $html .= '<li><a href="' . $child->getHtmlUrl() . '" class="name1">' . $child->getFullName() . '</a></li>';
                             }
                             $html .= '</ul>';
                         }
                     }
                 }
                 // siblings
                 foreach ($person->getChildFamilies() as $family) {
                     $children = $family->getChildren();
                     if ($children) {
                         $html .= '<div class="name1">';
                         // With two children in a family, you have only one sibling.
                         $html .= count($children) > 2 ? I18N::translate('Siblings') : I18N::translate('Sibling');
                         $html .= '</div>';
                         $html .= '<ul class="siblings">';
                         foreach ($children as $sibling) {
                             if ($sibling !== $person) {
                                 $html .= '<li><a href="' . $sibling->getHtmlUrl() . '" class="name1"> ' . $sibling->getFullName() . '</a></li>';
                             }
                         }
                         $html .= '</ul>';
                     }
                 }
                 $html .= '</div></div>';
                 $html .= '</div>';
                 $imagemap .= ' alt="' . strip_tags($person->getFullName()) . '" title="' . strip_tags($person->getFullName()) . '">';
             }
             $deg1 -= $angle;
             $deg2 -= $angle;
             $sosa--;
         }
         $rx -= $rw;
         $gen--;
     }
     $imagemap .= '</map>';
     switch ($what) {
         case 'html':
             return $html . $imagemap . '<div id="fan_chart_img"><img src="' . WT_SCRIPT_NAME . '?rootid=' . $this->root->getXref() . '&amp;fan_style=' . $this->fan_style . '&amp;generations=' . $this->generations . '&amp;fan_width=' . $this->fan_width . '&amp;img=1" width="' . $fanw . '" height="' . $fanh . '" alt="' . strip_tags($this->getPageTitle()) . '" usemap="#fanmap"></div>';
         case 'png':
             ImageStringUp($image, 1, $fanw - 10, $fanh / 3, WT_BASE_URL, $color);
             ob_start();
             ImagePng($image);
             ImageDestroy($image);
             return ob_get_clean();
         default:
             throw new \InvalidArgumentException(__METHOD__ . ' ' . $what);
     }
 }
예제 #29
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 $controller;
        $id = $this->getName() . $block_id;
        $class = $this->getName() . '_block';
        $controller->addInlineJavascript('
			jQuery("#new_passwd").hide();
			jQuery("#passwd_click").click(function() {
				jQuery("#new_passwd").slideToggle(100, function() {
					jQuery("#new_passwd_username").focus();
				});
				return false;
			});
		');
        if (Auth::check()) {
            $title = I18N::translate('Logout');
            $content = '<div class="center"><form method="post" action="logout.php" name="logoutform" onsubmit="return true;">';
            $content .= '<br><a href="../../edituser.php" class="name2">' . I18N::translate('Logged in as ') . ' ' . Auth::user()->getRealNameHtml() . '</a><br><br>';
            $content .= '<input type="submit" value="' . I18N::translate('Logout') . '">';
            $content .= '<br><br></form></div>';
        } else {
            $title = I18N::translate('Login');
            $content = '<div id="login-box">
				<form id="login-form" name="login-form" method="post" action="' . WT_LOGIN_URL . '">
				<input type="hidden" name="action" value="login">';
            $content .= '<div>
				<label for="username">' . I18N::translate('Username') . '<input type="text" id="username" name="username" class="formField">
				</label>
				</div>
				<div>
					<label for="password">' . I18N::translate('Password') . '<input type="password" id="password" name="password" class="formField">
					</label>
				</div>
				<div>
					<input type="submit" value="' . I18N::translate('Login') . '">
				</div>
				<div>
					<a href="#" id="passwd_click">' . I18N::translate('Request new password') . '</a>
				</div>';
            if (Site::getPreference('USE_REGISTRATION_MODULE')) {
                $content .= '<div><a href="' . WT_LOGIN_URL . '?action=register">' . I18N::translate('Request new user account') . '</a></div>';
            }
            $content .= '</form>';
            // close "login-form"
            // hidden New Password block
            $content .= '<div id="new_passwd">
			<form id="new_passwd_form" name="new_passwd_form" action="' . WT_LOGIN_URL . '" method="post">
			<input type="hidden" name="time" value="">
			<input type="hidden" name="action" value="requestpw">
			<h4>' . I18N::translate('Lost password request') . '</h4>
			<div>
				<label for="new_passwd_username">' . I18N::translate('Username or email address') . '<input type="text" id="new_passwd_username" name="new_passwd_username" value="">
				</label>
			</div>
			<div><input type="submit" value="' . I18N::translate('continue') . '"></div>
			</form>
		</div>';
            //"new_passwd"
            $content .= '</div>';
            //"login-box"
        }
        if ($template) {
            return Theme::theme()->formatBlock($id, $title, $class, $content);
        } else {
            return $content;
        }
    }
예제 #30
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);
 }