.
*/
use PDO;
use PDOException;
use Rhumsaa\Uuid\Uuid;
/**
* Class FamilyTreeFavoritesModule
*
* Note that the user favorites module simply extends this module, so ensure that the
* logic works for both.
*/
class FamilyTreeFavoritesModule extends Module implements ModuleBlockInterface {
/** {@inheritdoc} */
public function getTitle() {
return /* I18N: Name of a module */ I18N::translate('Favorites');
}
/** {@inheritdoc} */
public function getDescription() {
return /* I18N: Description of the “Favorites” module */ I18N::translate('Display and manage a family tree’s favorite pages.');
}
/** {@inheritdoc} */
public function getBlock($block_id, $template = true, $cfg = null) {
global $ctype, $controller, $WT_TREE;
self::updateSchema(); // make sure the favorites table has been created
$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 = get_block_setting($block_id, 'block', '0');
if ($cfg) {
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 = '' . I18N::translate('Remove') . ' ';
if ($favorite['type'] == 'URL') {
$content .= '
';
if ($ctype == 'user' || Auth::isManager($WT_TREE)) {
$content .= $removeFavourite;
}
$content .= '
' . $favorite['title'] . '';
$content .= '
' . $favorite['note'];
$content .= '
';
} else {
$record = GedcomRecord::getInstance($favorite['gid'], $WT_TREE);
if ($record && $record->canShow()) {
if ($record instanceof Individual) {
$content .= '';
} else {
$content .= '';
if ($ctype == 'user' || Auth::isManager($WT_TREE)) {
$content .= $removeFavourite;
}
$content .= $record->formatList('span');
$content .= '
' . $favorite['note'];
$content .= '
';
}
}
}
}
}
if ($ctype == 'user' || Auth::isManager($WT_TREE)) {
$uniqueID = Uuid::uuid4(); // This block can theoretically appear multiple times, so use a unique ID.
$content .= '';
$content .= '';
}
if ($template) {
if ($block) {
$class .= ' small_inner_block';
}
return Theme::theme()->formatBlock($id, $title, $class, $content);
} else {
return $content;
}
}
/** {@inheritdoc} */
public function loadAjax() {
return false;
}
/** {@inheritdoc} */
public function isUserBlock() {
return false;
}
/** {@inheritdoc} */
public function isGedcomBlock() {
return true;
}
/** {@inheritdoc} */
public function configureBlock($block_id) {
if (Filter::postBool('save') && Filter::checkCsrf()) {
set_block_setting($block_id, 'block', Filter::postBool('block'));
}
$block = get_block_setting($block_id, 'block', '0');
echo '';
echo /* I18N: label for a yes/no option */ I18N::translate('Add a scrollbar when block contents grow');
echo ' | ';
echo edit_field_yes_no('block', $block);
echo ' |
';
}
/**
* Delete a favorite from the database
*
* @param integer $favorite_id
*
* @return boolean
*/
public static function deleteFavorite($favorite_id) {
return (bool)
Database::prepare("DELETE FROM `##favorite` WHERE favorite_id=?")
->execute(array($favorite_id));
}
/**
* Store a new favorite in the database
*
* @param $favorite
*
* @return boolean
*/
public static function addFavorite($favorite) {
// -- make sure a favorite is added
if (empty($favorite['gid']) && empty($favorite['url'])) {
return false;
}
//-- make sure this is not a duplicate entry
$sql = "SELECT SQL_NO_CACHE 1 FROM `##favorite` WHERE";
if (!empty($favorite['gid'])) {
$sql .= " xref=?";
$vars = array($favorite['gid']);
} else {
$sql .= " url=?";
$vars = array($favorite['url']);
}
$sql .= " AND gedcom_id=?";
$vars[] = $favorite['gedcom_id'];
if ($favorite['user_id']) {
$sql .= " AND user_id=?";
$vars[] = $favorite['user_id'];
} else {
$sql .= " AND user_id IS NULL";
}
if (Database::prepare($sql)->execute($vars)->fetchOne()) {
return false;
}
//-- add the favorite to the database
return (bool)
Database::prepare("INSERT INTO `##favorite` (user_id, gedcom_id, xref, favorite_type, url, title, note) VALUES (? ,? ,? ,? ,? ,? ,?)")
->execute(array($favorite['user_id'], $favorite['gedcom_id'], $favorite['gid'], $favorite['type'], $favorite['url'], $favorite['title'], $favorite['note']));
}
/**
* Get favorites for a user or family tree
*
* @param integer $gedcom_id
*
* @return string[][]
*/
public static function getFavorites($gedcom_id) {
self::updateSchema(); // make sure the favorites table has been created
return
Database::prepare(
"SELECT SQL_CACHE favorite_id AS id, user_id, gedcom_id, xref AS gid, favorite_type AS type, title, note, url" .
" FROM `##favorite` WHERE gedcom_id=? AND user_id IS NULL")
->execute(array($gedcom_id))
->fetchAll(PDO::FETCH_ASSOC);
}
/**
* Make sure the database structure is up-to-date.
*/
protected static function updateSchema() {
// Create tables, if not already present
try {
Database::updateSchema(WT_ROOT . WT_MODULES_DIR . 'gedcom_favorites/db_schema/', 'FV_SCHEMA_VERSION', 4);
} catch (PDOException $ex) {
// The schema update scripts should never fail. If they do, there is no clean recovery.
FlashMessages::addMessage($ex->getMessage(), 'danger');
header('Location: ' . WT_BASE_URL . 'site-unavailable.php');
throw $ex;
}
}
}