/** * Import data from each file. */ function importFiles($fileNames) { foreach ($fileNames as $fileName) { if (file_exists($fileName)) { printf("Importing: %s.\n", $fileName); try { importFile($fileName); } catch (Exception $e) { printf("\tSkipped: %s\n", $e->getMessage()); } } else { printf("Skipped: %s. File does not exist.\n", $fileName); } } }
function renderPage() { $LINKSDB = new LinkDB($GLOBALS['config']['DATASTORE'], isLoggedIn(), $GLOBALS['config']['HIDE_PUBLIC_LINKS'], $GLOBALS['redirector'], $GLOBALS['config']['REDIRECTOR_URLENCODE']); $updater = new Updater(read_updates_file($GLOBALS['config']['UPDATES_FILE']), $GLOBALS, $LINKSDB, isLoggedIn()); try { $newUpdates = $updater->update(); if (!empty($newUpdates)) { write_updates_file($GLOBALS['config']['UPDATES_FILE'], $updater->getDoneUpdates()); } } catch (Exception $e) { die($e->getMessage()); } $PAGE = new PageBuilder(); $PAGE->assign('linkcount', count($LINKSDB)); $PAGE->assign('privateLinkcount', count_private($LINKSDB)); // Determine which page will be rendered. $query = isset($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : ''; $targetPage = Router::findPage($query, $_GET, isLoggedIn()); // Call plugin hooks for header, footer and includes, specifying which page will be rendered. // Then assign generated data to RainTPL. $common_hooks = array('includes', 'header', 'footer'); $pluginManager = PluginManager::getInstance(); foreach ($common_hooks as $name) { $plugin_data = array(); $pluginManager->executeHooks('render_' . $name, $plugin_data, array('target' => $targetPage, 'loggedin' => isLoggedIn())); $PAGE->assign('plugins_' . $name, $plugin_data); } // -------- Display login form. if ($targetPage == Router::$PAGE_LOGIN) { if ($GLOBALS['config']['OPEN_SHAARLI']) { header('Location: ?'); exit; } // No need to login for open Shaarli $token = ''; if (ban_canLogin()) { $token = getToken(); } // Do not waste token generation if not useful. $PAGE->assign('token', $token); if (isset($_GET['username'])) { $PAGE->assign('username', escape($_GET['username'])); } $PAGE->assign('returnurl', isset($_SERVER['HTTP_REFERER']) ? escape($_SERVER['HTTP_REFERER']) : ''); $PAGE->renderPage('loginform'); exit; } // -------- User wants to logout. if (isset($_SERVER['QUERY_STRING']) && startsWith($_SERVER['QUERY_STRING'], 'do=logout')) { invalidateCaches($GLOBALS['config']['PAGECACHE']); logout(); header('Location: ?'); exit; } // -------- Picture wall if ($targetPage == Router::$PAGE_PICWALL) { // Optionally filter the results: $links = $LINKSDB->filterSearch($_GET); $linksToDisplay = array(); // Get only links which have a thumbnail. foreach ($links as $link) { $permalink = '?' . escape(smallhash($link['linkdate'])); $thumb = lazyThumbnail($link['url'], $permalink); if ($thumb != '') { $link['thumbnail'] = $thumb; // Thumbnail HTML code. $linksToDisplay[] = $link; // Add to array. } } $data = array('linksToDisplay' => $linksToDisplay); $pluginManager->executeHooks('render_picwall', $data, array('loggedin' => isLoggedIn())); foreach ($data as $key => $value) { $PAGE->assign($key, $value); } $PAGE->renderPage('picwall'); exit; } // -------- Tag cloud if ($targetPage == Router::$PAGE_TAGCLOUD) { $tags = $LINKSDB->allTags(); // We sort tags alphabetically, then choose a font size according to count. // First, find max value. $maxcount = 0; foreach ($tags as $value) { $maxcount = max($maxcount, $value); } // Sort tags alphabetically: case insensitive, support locale if avalaible. uksort($tags, function ($a, $b) { // Collator is part of PHP intl. if (class_exists('Collator')) { $c = new Collator(setlocale(LC_COLLATE, 0)); if (!intl_is_failure(intl_get_error_code())) { return $c->compare($a, $b); } } return strcasecmp($a, $b); }); $tagList = array(); foreach ($tags as $key => $value) { // Tag font size scaling: // default 15 and 30 logarithm bases affect scaling, // 22 and 6 are arbitrary font sizes for max and min sizes. $size = log($value, 15) / log($maxcount, 30) * 2.2 + 0.8; $tagList[$key] = array('count' => $value, 'size' => number_format($size, 2, '.', '')); } $data = array('tags' => $tagList); $pluginManager->executeHooks('render_tagcloud', $data, array('loggedin' => isLoggedIn())); foreach ($data as $key => $value) { $PAGE->assign($key, $value); } $PAGE->renderPage('tagcloud'); exit; } // Daily page. if ($targetPage == Router::$PAGE_DAILY) { showDaily($PAGE, $LINKSDB); } // ATOM and RSS feed. if ($targetPage == Router::$PAGE_FEED_ATOM || $targetPage == Router::$PAGE_FEED_RSS) { $feedType = $targetPage == Router::$PAGE_FEED_RSS ? FeedBuilder::$FEED_RSS : FeedBuilder::$FEED_ATOM; header('Content-Type: application/' . $feedType . '+xml; charset=utf-8'); // Cache system $query = $_SERVER['QUERY_STRING']; $cache = new CachedPage($GLOBALS['config']['PAGECACHE'], page_url($_SERVER), startsWith($query, 'do=' . $targetPage) && !isLoggedIn()); $cached = $cache->cachedVersion(); if (!empty($cached)) { echo $cached; exit; } // Generate data. $feedGenerator = new FeedBuilder($LINKSDB, $feedType, $_SERVER, $_GET, isLoggedIn()); $feedGenerator->setLocale(strtolower(setlocale(LC_COLLATE, 0))); $feedGenerator->setHideDates($GLOBALS['config']['HIDE_TIMESTAMPS'] && !isLoggedIn()); $feedGenerator->setUsePermalinks(isset($_GET['permalinks']) || !$GLOBALS['config']['ENABLE_RSS_PERMALINKS']); if (!empty($GLOBALS['config']['PUBSUBHUB_URL'])) { $feedGenerator->setPubsubhubUrl($GLOBALS['config']['PUBSUBHUB_URL']); } $data = $feedGenerator->buildData(); // Process plugin hook. $pluginManager = PluginManager::getInstance(); $pluginManager->executeHooks('render_feed', $data, array('loggedin' => isLoggedIn(), 'target' => $targetPage)); // Render the template. $PAGE->assignAll($data); $PAGE->renderPage('feed.' . $feedType); $cache->cache(ob_get_contents()); ob_end_flush(); exit; } // Display openseach plugin (XML) if ($targetPage == Router::$PAGE_OPENSEARCH) { header('Content-Type: application/xml; charset=utf-8'); $PAGE->assign('serverurl', index_url($_SERVER)); $PAGE->renderPage('opensearch'); exit; } // -------- User clicks on a tag in a link: The tag is added to the list of searched tags (searchtags=...) if (isset($_GET['addtag'])) { // Get previous URL (http_referer) and add the tag to the searchtags parameters in query. if (empty($_SERVER['HTTP_REFERER'])) { header('Location: ?searchtags=' . urlencode($_GET['addtag'])); exit; } // In case browser does not send HTTP_REFERER parse_str(parse_url($_SERVER['HTTP_REFERER'], PHP_URL_QUERY), $params); // Prevent redirection loop if (isset($params['addtag'])) { unset($params['addtag']); } // Check if this tag is already in the search query and ignore it if it is. // Each tag is always separated by a space if (isset($params['searchtags'])) { $current_tags = explode(' ', $params['searchtags']); } else { $current_tags = array(); } $addtag = true; foreach ($current_tags as $value) { if ($value === $_GET['addtag']) { $addtag = false; break; } } // Append the tag if necessary if (empty($params['searchtags'])) { $params['searchtags'] = trim($_GET['addtag']); } else { if ($addtag) { $params['searchtags'] = trim($params['searchtags']) . ' ' . trim($_GET['addtag']); } } unset($params['page']); // We also remove page (keeping the same page has no sense, since the results are different) header('Location: ?' . http_build_query($params)); exit; } // -------- User clicks on a tag in result count: Remove the tag from the list of searched tags (searchtags=...) if (isset($_GET['removetag'])) { // Get previous URL (http_referer) and remove the tag from the searchtags parameters in query. if (empty($_SERVER['HTTP_REFERER'])) { header('Location: ?'); exit; } // In case browser does not send HTTP_REFERER parse_str(parse_url($_SERVER['HTTP_REFERER'], PHP_URL_QUERY), $params); // Prevent redirection loop if (isset($params['removetag'])) { unset($params['removetag']); } if (isset($params['searchtags'])) { $tags = explode(' ', $params['searchtags']); // Remove value from array $tags. $tags = array_diff($tags, array($_GET['removetag'])); $params['searchtags'] = implode(' ', $tags); if (empty($params['searchtags'])) { unset($params['searchtags']); } unset($params['page']); // We also remove page (keeping the same page has no sense, since the results are different) } header('Location: ?' . http_build_query($params)); exit; } // -------- User wants to change the number of links per page (linksperpage=...) if (isset($_GET['linksperpage'])) { if (is_numeric($_GET['linksperpage'])) { $_SESSION['LINKS_PER_PAGE'] = abs(intval($_GET['linksperpage'])); } header('Location: ' . generateLocation($_SERVER['HTTP_REFERER'], $_SERVER['HTTP_HOST'], array('linksperpage'))); exit; } // -------- User wants to see only private links (toggle) if (isset($_GET['privateonly'])) { if (empty($_SESSION['privateonly'])) { $_SESSION['privateonly'] = 1; // See only private links } else { unset($_SESSION['privateonly']); // See all links } header('Location: ' . generateLocation($_SERVER['HTTP_REFERER'], $_SERVER['HTTP_HOST'], array('privateonly'))); exit; } // -------- Handle other actions allowed for non-logged in users: if (!isLoggedIn()) { // User tries to post new link but is not logged in: // Show login screen, then redirect to ?post=... if (isset($_GET['post'])) { header('Location: ?do=login&post=' . urlencode($_GET['post']) . (!empty($_GET['title']) ? '&title=' . urlencode($_GET['title']) : '') . (!empty($_GET['description']) ? '&description=' . urlencode($_GET['description']) : '') . (!empty($_GET['source']) ? '&source=' . urlencode($_GET['source']) : '')); // Redirect to login page, then back to post link. exit; } showLinkList($PAGE, $LINKSDB); if (isset($_GET['edit_link'])) { header('Location: ?do=login&edit_link=' . escape($_GET['edit_link'])); exit; } exit; // Never remove this one! All operations below are reserved for logged in user. } // -------- All other functions are reserved for the registered user: // -------- Display the Tools menu if requested (import/export/bookmarklet...) if ($targetPage == Router::$PAGE_TOOLS) { $data = array('pageabsaddr' => index_url($_SERVER)); $pluginManager->executeHooks('render_tools', $data); foreach ($data as $key => $value) { $PAGE->assign($key, $value); } $PAGE->renderPage('tools'); exit; } // -------- User wants to change his/her password. if ($targetPage == Router::$PAGE_CHANGEPASSWORD) { if ($GLOBALS['config']['OPEN_SHAARLI']) { die('You are not supposed to change a password on an Open Shaarli.'); } if (!empty($_POST['setpassword']) && !empty($_POST['oldpassword'])) { if (!tokenOk($_POST['token'])) { die('Wrong token.'); } // Go away! // Make sure old password is correct. $oldhash = sha1($_POST['oldpassword'] . $GLOBALS['login'] . $GLOBALS['salt']); if ($oldhash != $GLOBALS['hash']) { echo '<script>alert("The old password is not correct.");document.location=\'?do=changepasswd\';</script>'; exit; } // Save new password $GLOBALS['salt'] = sha1(uniqid('', true) . '_' . mt_rand()); // Salt renders rainbow-tables attacks useless. $GLOBALS['hash'] = sha1($_POST['setpassword'] . $GLOBALS['login'] . $GLOBALS['salt']); try { writeConfig($GLOBALS, isLoggedIn()); } catch (Exception $e) { error_log('ERROR while writing config file after changing password.' . PHP_EOL . $e->getMessage()); // TODO: do not handle exceptions/errors in JS. echo '<script>alert("' . $e->getMessage() . '");document.location=\'?do=tools\';</script>'; exit; } echo '<script>alert("Your password has been changed.");document.location=\'?do=tools\';</script>'; exit; } else { $PAGE->assign('token', getToken()); $PAGE->renderPage('changepassword'); exit; } } // -------- User wants to change configuration if ($targetPage == Router::$PAGE_CONFIGURE) { if (!empty($_POST['title'])) { if (!tokenOk($_POST['token'])) { die('Wrong token.'); // Go away! } $tz = 'UTC'; if (!empty($_POST['continent']) && !empty($_POST['city']) && isTimeZoneValid($_POST['continent'], $_POST['city'])) { $tz = $_POST['continent'] . '/' . $_POST['city']; } $GLOBALS['timezone'] = $tz; $GLOBALS['title'] = $_POST['title']; $GLOBALS['titleLink'] = $_POST['titleLink']; $GLOBALS['redirector'] = $_POST['redirector']; $GLOBALS['disablesessionprotection'] = !empty($_POST['disablesessionprotection']); $GLOBALS['privateLinkByDefault'] = !empty($_POST['privateLinkByDefault']); $GLOBALS['config']['ENABLE_RSS_PERMALINKS'] = !empty($_POST['enableRssPermalinks']); $GLOBALS['config']['ENABLE_UPDATECHECK'] = !empty($_POST['updateCheck']); $GLOBALS['config']['HIDE_PUBLIC_LINKS'] = !empty($_POST['hidePublicLinks']); try { writeConfig($GLOBALS, isLoggedIn()); } catch (Exception $e) { error_log('ERROR while writing config file after configuration update.' . PHP_EOL . $e->getMessage()); // TODO: do not handle exceptions/errors in JS. echo '<script>alert("' . $e->getMessage() . '");document.location=\'?do=tools\';</script>'; exit; } echo '<script>alert("Configuration was saved.");document.location=\'?do=tools\';</script>'; exit; } else { $PAGE->assign('token', getToken()); $PAGE->assign('title', empty($GLOBALS['title']) ? '' : $GLOBALS['title']); $PAGE->assign('redirector', empty($GLOBALS['redirector']) ? '' : $GLOBALS['redirector']); list($timezone_form, $timezone_js) = generateTimeZoneForm($GLOBALS['timezone']); $PAGE->assign('timezone_form', $timezone_form); $PAGE->assign('timezone_js', $timezone_js); $PAGE->renderPage('configure'); exit; } } // -------- User wants to rename a tag or delete it if ($targetPage == Router::$PAGE_CHANGETAG) { if (empty($_POST['fromtag']) || empty($_POST['totag']) && isset($_POST['renametag'])) { $PAGE->assign('token', getToken()); $PAGE->assign('tags', $LINKSDB->allTags()); $PAGE->renderPage('changetag'); exit; } if (!tokenOk($_POST['token'])) { die('Wrong token.'); } // Delete a tag: if (isset($_POST['deletetag']) && !empty($_POST['fromtag'])) { $needle = trim($_POST['fromtag']); // True for case-sensitive tag search. $linksToAlter = $LINKSDB->filterSearch(array('searchtags' => $needle), true); foreach ($linksToAlter as $key => $value) { $tags = explode(' ', trim($value['tags'])); unset($tags[array_search($needle, $tags)]); // Remove tag. $value['tags'] = trim(implode(' ', $tags)); $LINKSDB[$key] = $value; } $LINKSDB->savedb($GLOBALS['config']['PAGECACHE']); echo '<script>alert("Tag was removed from ' . count($linksToAlter) . ' links.");document.location=\'?\';</script>'; exit; } // Rename a tag: if (isset($_POST['renametag']) && !empty($_POST['fromtag']) && !empty($_POST['totag'])) { $needle = trim($_POST['fromtag']); // True for case-sensitive tag search. $linksToAlter = $LINKSDB->filterSearch(array('searchtags' => $needle), true); foreach ($linksToAlter as $key => $value) { $tags = explode(' ', trim($value['tags'])); $tags[array_search($needle, $tags)] = trim($_POST['totag']); // Replace tags value. $value['tags'] = trim(implode(' ', $tags)); $LINKSDB[$key] = $value; } $LINKSDB->savedb($GLOBALS['config']['PAGECACHE']); // Save to disk. echo '<script>alert("Tag was renamed in ' . count($linksToAlter) . ' links.");document.location=\'?searchtags=' . urlencode($_POST['totag']) . '\';</script>'; exit; } } // -------- User wants to add a link without using the bookmarklet: Show form. if ($targetPage == Router::$PAGE_ADDLINK) { $PAGE->renderPage('addlink'); exit; } // -------- User clicked the "Save" button when editing a link: Save link to database. if (isset($_POST['save_edit'])) { // Go away! if (!tokenOk($_POST['token'])) { die('Wrong token.'); } // Remove multiple spaces. $tags = trim(preg_replace('/\\s\\s+/', ' ', $_POST['lf_tags'])); // Remove first '-' char in tags. $tags = preg_replace('/(^| )\\-/', '$1', $tags); // Remove duplicates. $tags = implode(' ', array_unique(explode(' ', $tags))); $linkdate = $_POST['lf_linkdate']; $url = trim($_POST['lf_url']); if (!startsWith($url, 'http:') && !startsWith($url, 'https:') && !startsWith($url, 'ftp:') && !startsWith($url, 'magnet:') && !startsWith($url, '?') && !startsWith($url, 'javascript:')) { $url = 'http://' . $url; } $link = array('title' => trim($_POST['lf_title']), 'url' => $url, 'description' => $_POST['lf_description'], 'private' => isset($_POST['lf_private']) ? 1 : 0, 'linkdate' => $linkdate, 'tags' => str_replace(',', ' ', $tags)); // If title is empty, use the URL as title. if ($link['title'] == '') { $link['title'] = $link['url']; } $pluginManager->executeHooks('save_link', $link); $LINKSDB[$linkdate] = $link; $LINKSDB->savedb($GLOBALS['config']['PAGECACHE']); pubsubhub(); // If we are called from the bookmarklet, we must close the popup: if (isset($_GET['source']) && ($_GET['source'] == 'bookmarklet' || $_GET['source'] == 'firefoxsocialapi')) { echo '<script>self.close();</script>'; exit; } $returnurl = !empty($_POST['returnurl']) ? $_POST['returnurl'] : '?'; $location = generateLocation($returnurl, $_SERVER['HTTP_HOST'], array('addlink', 'post', 'edit_link')); // Scroll to the link which has been edited. $location .= '#' . smallHash($_POST['lf_linkdate']); // After saving the link, redirect to the page the user was on. header('Location: ' . $location); exit; } // -------- User clicked the "Cancel" button when editing a link. if (isset($_POST['cancel_edit'])) { // If we are called from the bookmarklet, we must close the popup: if (isset($_GET['source']) && ($_GET['source'] == 'bookmarklet' || $_GET['source'] == 'firefoxsocialapi')) { echo '<script>self.close();</script>'; exit; } $returnurl = isset($_POST['returnurl']) ? $_POST['returnurl'] : '?'; $returnurl .= '#' . smallHash($_POST['lf_linkdate']); // Scroll to the link which has been edited. $returnurl = generateLocation($returnurl, $_SERVER['HTTP_HOST'], array('addlink', 'post', 'edit_link')); header('Location: ' . $returnurl); // After canceling, redirect to the page the user was on. exit; } // -------- User clicked the "Delete" button when editing a link: Delete link from database. if (isset($_POST['delete_link'])) { if (!tokenOk($_POST['token'])) { die('Wrong token.'); } // We do not need to ask for confirmation: // - confirmation is handled by JavaScript // - we are protected from XSRF by the token. $linkdate = $_POST['lf_linkdate']; $pluginManager->executeHooks('delete_link', $LINKSDB[$linkdate]); unset($LINKSDB[$linkdate]); $LINKSDB->savedb($GLOBALS['config']['PAGECACHE']); // save to disk // If we are called from the bookmarklet, we must close the popup: if (isset($_GET['source']) && ($_GET['source'] == 'bookmarklet' || $_GET['source'] == 'firefoxsocialapi')) { echo '<script>self.close();</script>'; exit; } // Pick where we're going to redirect // ============================================================= // Basically, we can't redirect to where we were previously if it was a permalink // or an edit_link, because it would 404. // Cases: // - / : nothing in $_GET, redirect to self // - /?page : redirect to self // - /?searchterm : redirect to self (there might be other links) // - /?searchtags : redirect to self // - /permalink : redirect to / (the link does not exist anymore) // - /?edit_link : redirect to / (the link does not exist anymore) // PHP treats the permalink as a $_GET variable, so we need to check if every condition for self // redirect is not satisfied, and only then redirect to / $location = "?"; // Self redirection if (count($_GET) == 0 || isset($_GET['page']) || isset($_GET['searchterm']) || isset($_GET['searchtags'])) { if (isset($_POST['returnurl'])) { $location = $_POST['returnurl']; // Handle redirects given by the form } else { $location = generateLocation($_SERVER['HTTP_REFERER'], $_SERVER['HTTP_HOST'], array('delete_link')); } } header('Location: ' . $location); // After deleting the link, redirect to appropriate location exit; } // -------- User clicked the "EDIT" button on a link: Display link edit form. if (isset($_GET['edit_link'])) { $link = $LINKSDB[$_GET['edit_link']]; // Read database if (!$link) { header('Location: ?'); exit; } // Link not found in database. $data = array('link' => $link, 'link_is_new' => false, 'token' => getToken(), 'http_referer' => isset($_SERVER['HTTP_REFERER']) ? escape($_SERVER['HTTP_REFERER']) : '', 'tags' => $LINKSDB->allTags()); $pluginManager->executeHooks('render_editlink', $data); foreach ($data as $key => $value) { $PAGE->assign($key, $value); } $PAGE->renderPage('editlink'); exit; } // -------- User want to post a new link: Display link edit form. if (isset($_GET['post'])) { $url = cleanup_url($_GET['post']); $link_is_new = false; // Check if URL is not already in database (in this case, we will edit the existing link) $link = $LINKSDB->getLinkFromUrl($url); if (!$link) { $link_is_new = true; $linkdate = strval(date('Ymd_His')); // Get title if it was provided in URL (by the bookmarklet). $title = empty($_GET['title']) ? '' : escape($_GET['title']); // Get description if it was provided in URL (by the bookmarklet). [Bronco added that] $description = empty($_GET['description']) ? '' : escape($_GET['description']); $tags = empty($_GET['tags']) ? '' : escape($_GET['tags']); $private = !empty($_GET['private']) && $_GET['private'] === "1" ? 1 : 0; // If this is an HTTP(S) link, we try go get the page to extract the title (otherwise we will to straight to the edit form.) if (empty($title) && strpos(get_url_scheme($url), 'http') !== false) { // Short timeout to keep the application responsive list($headers, $content) = get_http_response($url, 4); if (strpos($headers[0], '200 OK') !== false) { // Retrieve charset. $charset = get_charset($headers, $content); // Extract title. $title = html_extract_title($content); // Re-encode title in utf-8 if necessary. if (!empty($title) && strtolower($charset) != 'utf-8') { $title = mb_convert_encoding($title, 'utf-8', $charset); } } } if ($url == '') { $url = '?' . smallHash($linkdate); $title = 'Note: '; } $url = escape($url); $title = escape($title); $link = array('linkdate' => $linkdate, 'title' => $title, 'url' => $url, 'description' => $description, 'tags' => $tags, 'private' => $private); } $data = array('link' => $link, 'link_is_new' => $link_is_new, 'token' => getToken(), 'http_referer' => isset($_SERVER['HTTP_REFERER']) ? escape($_SERVER['HTTP_REFERER']) : '', 'source' => isset($_GET['source']) ? $_GET['source'] : '', 'tags' => $LINKSDB->allTags()); $pluginManager->executeHooks('render_editlink', $data); foreach ($data as $key => $value) { $PAGE->assign($key, $value); } $PAGE->renderPage('editlink'); exit; } if ($targetPage == Router::$PAGE_EXPORT) { // Export links as a Netscape Bookmarks file if (empty($_GET['selection'])) { $PAGE->renderPage('export'); exit; } // export as bookmarks_(all|private|public)_YYYYmmdd_HHMMSS.html $selection = $_GET['selection']; if (isset($_GET['prepend_note_url'])) { $prependNoteUrl = $_GET['prepend_note_url']; } else { $prependNoteUrl = false; } try { $PAGE->assign('links', NetscapeBookmarkUtils::filterAndFormat($LINKSDB, $selection, $prependNoteUrl, index_url($_SERVER))); } catch (Exception $exc) { header('Content-Type: text/plain; charset=utf-8'); echo $exc->getMessage(); exit; } $now = new DateTime(); header('Content-Type: text/html; charset=utf-8'); header('Content-disposition: attachment; filename=bookmarks_' . $selection . '_' . $now->format(LinkDB::LINK_DATE_FORMAT) . '.html'); $PAGE->assign('date', $now->format(DateTime::RFC822)); $PAGE->assign('eol', PHP_EOL); $PAGE->assign('selection', $selection); $PAGE->renderPage('export.bookmarks'); exit; } // -------- User is uploading a file for import if (isset($_SERVER['QUERY_STRING']) && startsWith($_SERVER['QUERY_STRING'], 'do=upload')) { // If file is too big, some form field may be missing. if (!isset($_POST['token']) || !isset($_FILES) || isset($_FILES['filetoupload']['size']) && $_FILES['filetoupload']['size'] == 0) { $returnurl = empty($_SERVER['HTTP_REFERER']) ? '?' : $_SERVER['HTTP_REFERER']; echo '<script>alert("The file you are trying to upload is probably bigger than what this webserver can accept (' . getMaxFileSize() . ' bytes). Please upload in smaller chunks.");document.location=\'' . escape($returnurl) . '\';</script>'; exit; } if (!tokenOk($_POST['token'])) { die('Wrong token.'); } importFile($LINKSDB); exit; } // -------- Show upload/import dialog: if ($targetPage == Router::$PAGE_IMPORT) { $PAGE->assign('token', getToken()); $PAGE->assign('maxfilesize', getMaxFileSize()); $PAGE->renderPage('import'); exit; } // Plugin administration page if ($targetPage == Router::$PAGE_PLUGINSADMIN) { $pluginMeta = $pluginManager->getPluginsMeta(); // Split plugins into 2 arrays: ordered enabled plugins and disabled. $enabledPlugins = array_filter($pluginMeta, function ($v) { return $v['order'] !== false; }); // Load parameters. $enabledPlugins = load_plugin_parameter_values($enabledPlugins, $GLOBALS['plugins']); uasort($enabledPlugins, function ($a, $b) { return $a['order'] - $b['order']; }); $disabledPlugins = array_filter($pluginMeta, function ($v) { return $v['order'] === false; }); $PAGE->assign('enabledPlugins', $enabledPlugins); $PAGE->assign('disabledPlugins', $disabledPlugins); $PAGE->renderPage('pluginsadmin'); exit; } // Plugin administration form action if ($targetPage == Router::$PAGE_SAVE_PLUGINSADMIN) { try { if (isset($_POST['parameters_form'])) { unset($_POST['parameters_form']); foreach ($_POST as $param => $value) { $GLOBALS['plugins'][$param] = escape($value); } } else { $GLOBALS['config']['ENABLED_PLUGINS'] = save_plugin_config($_POST); } writeConfig($GLOBALS, isLoggedIn()); } catch (Exception $e) { error_log('ERROR while saving plugin configuration:.' . PHP_EOL . $e->getMessage()); // TODO: do not handle exceptions/errors in JS. echo '<script>alert("' . $e->getMessage() . '");document.location=\'?do=' . Router::$PAGE_PLUGINSADMIN . '\';</script>'; exit; } header('Location: ?do=' . Router::$PAGE_PLUGINSADMIN); exit; } // -------- Otherwise, simply display search form and links: showLinkList($PAGE, $LINKSDB); exit; }
* @package Mediboard * @author SARL OpenXtrem <*****@*****.**> * @license GNU General Public License, see http://www.gnu.org/licenses/gpl.html * @version $Revision$ * @link http://www.mediboard.org */ CCanDo::checkAdmin(); ini_set("auto_detect_line_endings", true); $targetPath = "modules/system/ressources/firstnames.csv"; $start = CValue::post("start"); $count = CValue::post("step"); $callback = CValue::post("callback"); CApp::setTimeLimit(600); CApp::setMemoryLimit("512M"); CMbObject::$useObjectCache = false; importFile($targetPath, $start, $count); $start += $count; CAppUI::setConf("system import_firstname start", $start); CAppUI::setConf("system import_firstname step", $count); if ($callback) { CAppUI::js("{$callback}({$start},{$count})"); } CMbObject::$useObjectCache = true; CApp::rip(); /** * import the csv firstname file * * @param string $targetPath filepath * @param int $start start from * @param int $count step of import *
function renderPage() { $LINKSDB = new linkdb(isLoggedIn() || $GLOBALS['config']['OPEN_SHAARLI']); // Read links from database (and filter private links if used it not logged in). // -------- Display login form. if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"], 'do=login')) { if ($GLOBALS['config']['OPEN_SHAARLI']) { header('Location: ?'); exit; } // No need to login for open Shaarli $token = ''; if (ban_canLogin()) { $token = getToken(); } // Do not waste token generation if not useful. $PAGE = new pageBuilder(); $PAGE->assign('token', $token); $PAGE->assign('returnurl', isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ''); $PAGE->renderPage('loginform'); exit; } // -------- User wants to logout. if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"], 'do=logout')) { invalidateCaches(); logout(); header('Location: ?'); exit; } // -------- Picture wall if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"], 'do=picwall')) { // Optionnaly filter the results: $links = array(); if (!empty($_GET['searchterm'])) { $links = $LINKSDB->filterFulltext($_GET['searchterm']); } elseif (!empty($_GET['searchtags'])) { $links = $LINKSDB->filterTags(trim($_GET['searchtags'])); } else { $links = $LINKSDB; } $body = ''; $linksToDisplay = array(); // Get only links which have a thumbnail. foreach ($links as $link) { $permalink = '?' . htmlspecialchars(smallhash($link['linkdate']), ENT_QUOTES); $thumb = lazyThumbnail($link['url'], $permalink); if ($thumb != '') { $link['thumbnail'] = $thumb; // Thumbnail HTML code. $link['permalink'] = $permalink; $linksToDisplay[] = $link; // Add to array. } } $PAGE = new pageBuilder(); $PAGE->assign('linkcount', count($LINKSDB)); $PAGE->assign('linksToDisplay', $linksToDisplay); $PAGE->renderPage('picwall'); exit; } // -------- Tag cloud if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"], 'do=tagcloud')) { $tags = $LINKSDB->allTags(); // We sort tags alphabetically, then choose a font size according to count. // First, find max value. $maxcount = 0; foreach ($tags as $key => $value) { $maxcount = max($maxcount, $value); } ksort($tags); $tagList = array(); foreach ($tags as $key => $value) { $tagList[$key] = array('count' => $value, 'size' => max(40 * $value / $maxcount, 8)); } $PAGE = new pageBuilder(); $PAGE->assign('linkcount', count($LINKSDB)); $PAGE->assign('tags', $tagList); $PAGE->renderPage('tagcloud'); exit; } // -------- User clicks on a tag in a link: The tag is added to the list of searched tags (searchtags=...) if (isset($_GET['addtag'])) { // Get previous URL (http_referer) and add the tag to the searchtags parameters in query. if (empty($_SERVER['HTTP_REFERER'])) { header('Location: ?searchtags=' . urlencode($_GET['addtag'])); exit; } // In case browser does not send HTTP_REFERER parse_str(parse_url($_SERVER['HTTP_REFERER'], PHP_URL_QUERY), $params); $params['searchtags'] = empty($params['searchtags']) ? trim($_GET['addtag']) : trim($params['searchtags']) . ' ' . trim($_GET['addtag']); unset($params['page']); // We also remove page (keeping the same page has no sense, since the results are different) header('Location: ?' . http_build_query($params)); exit; } // -------- User clicks on a tag in result count: Remove the tag from the list of searched tags (searchtags=...) if (isset($_GET['removetag'])) { // Get previous URL (http_referer) and remove the tag from the searchtags parameters in query. if (empty($_SERVER['HTTP_REFERER'])) { header('Location: ?'); exit; } // In case browser does not send HTTP_REFERER parse_str(parse_url($_SERVER['HTTP_REFERER'], PHP_URL_QUERY), $params); if (isset($params['searchtags'])) { $tags = explode(' ', $params['searchtags']); $tags = array_diff($tags, array($_GET['removetag'])); // Remove value from array $tags. if (count($tags) == 0) { unset($params['searchtags']); } else { $params['searchtags'] = implode(' ', $tags); } unset($params['page']); // We also remove page (keeping the same page has no sense, since the results are different) } header('Location: ?' . http_build_query($params)); exit; } // -------- User wants to change the number of links per page (linksperpage=...) if (isset($_GET['linksperpage'])) { if (is_numeric($_GET['linksperpage'])) { $_SESSION['LINKS_PER_PAGE'] = abs(intval($_GET['linksperpage'])); } header('Location: ' . (empty($_SERVER['HTTP_REFERER']) ? '?' : $_SERVER['HTTP_REFERER'])); exit; } // -------- User wants to see only private links (toggle) if (isset($_GET['privateonly'])) { if (empty($_SESSION['privateonly'])) { $_SESSION['privateonly'] = 1; // See only private links } else { unset($_SESSION['privateonly']); // See all links } header('Location: ' . (empty($_SERVER['HTTP_REFERER']) ? '?' : $_SERVER['HTTP_REFERER'])); exit; } // --------- Weekly (all links form a specific week) ---------------------- if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"], 'do=weekly')) { $day_to_publish = 1; // 1 for monday, 7 for sunday $day_of_the_week = Date('N') - $day_to_publish; $week = Date('Ymd', time() - 3600 * 24 * $day_of_the_week); // one week ago if (isset($_GET['week'])) { $weektime = mktime(0, 0, 0, substr($_GET['week'], 4, 2), substr($_GET['week'], 6, 2), substr($_GET['week'], 0, 4)); $day_of_the_week = Date('N', $weektime) - $day_to_publish; $week = Date('Ymd', $weektime - 3600 * 24 * $day_of_the_week); // one week ago } $previousweek = Date('Ymd', strtotime('-7 days', strtotime($week))); $nextweek = Date('Ymd', strtotime('+7 days', strtotime($week))); $linksToDisplay = $LINKSDB->filterWeek($week); // We pre-format some fields for proper output. foreach ($linksToDisplay as $key => $link) { $linksToDisplay[$key]['taglist'] = explode(' ', $link['tags']); $linksToDisplay[$key]['formatedDescription'] = nl2br(keepMultipleSpaces(text2clickable(htmlspecialchars($link['description'])))); $linksToDisplay[$key]['thumbnail'] = thumbnail($link['url']); } /* We need to spread the articles on 3 columns. I did not want to use a javascript lib like http://masonry.desandro.com/ so I manually spread entries with a simple method: I roughly evaluate the height of a div according to title and description length. */ $columns = array(array(), array(), array()); // Entries to display, for each column. $fill = array(0, 0, 0); // Rough estimate of columns fill. foreach ($linksToDisplay as $key => $link) { // Roughly estimate length of entry (by counting characters) // Title: 30 chars = 1 line. 1 line is 30 pixels height. // Description: 836 characters gives roughly 342 pixel height. // This is not perfect, but it's usually ok. $length = strlen($link['title']) + 342 * strlen($link['description']) / 836; if ($link['thumbnail']) { $length += 100; } // 1 thumbnails roughly takes 100 pixels height. // Then put in column which is the less filled: $smallest = min($fill); // find smallest value in array. $index = array_search($smallest, $fill); // find index of this smallest value. array_push($columns[$index], $link); // Put entry in this column. $fill[$index] += $length; } $PAGE = new pageBuilder(); $PAGE->assign('linksToDisplay', $linksToDisplay); $PAGE->assign('col1', $columns[0]); $PAGE->assign('col2', $columns[1]); $PAGE->assign('col3', $columns[2]); $PAGE->assign('week', utf8_encode(strftime('%A %d, %B %Y', linkdate2timestamp($week . '_000000')))); $PAGE->assign('previousweek', $previousweek); $PAGE->assign('nextweek', $nextweek); $PAGE->renderPage('weekly'); exit; } // --------- Monthly (all links form a specific month) ---------------------- if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"], 'do=monthly')) { $month = Date('Ym', strtotime('-1 month')); // Previous month, in format YYYYMM. if (isset($_GET['month'])) { $month = $_GET['month']; } $months = $LINKSDB->months(); $i = array_search($month, $months); if ($i === false) { $i = count($months) - 1; $month = $months[$i]; } $previousmonth = ''; $nextmonth = ''; if ($i !== false) { if ($i >= 1) { $previousmonth = $months[$i - 1]; } if ($i < count($months) - 1) { $nextmonth = $months[$i + 1]; } } $linksToDisplay = $LINKSDB->filterMonth($month); // We pre-format some fields for proper output. foreach ($linksToDisplay as $key => $link) { $linksToDisplay[$key]['taglist'] = explode(' ', $link['tags']); $linksToDisplay[$key]['formatedDescription'] = nl2br(keepMultipleSpaces(text2clickable(htmlspecialchars($link['description'])))); $linksToDisplay[$key]['thumbnail'] = thumbnail($link['url']); } /* We need to spread the articles on 3 columns. I did not want to use a javascript lib like http://masonry.desandro.com/ so I manually spread entries with a simple method: I roughly evaluate the height of a div according to title and description length. */ $columns = array(array(), array(), array()); // Entries to display, for each column. $fill = array(0, 0, 0); // Rough estimate of columns fill. foreach ($linksToDisplay as $key => $link) { // Roughly estimate length of entry (by counting characters) // Title: 30 chars = 1 line. 1 line is 30 pixels height. // Description: 836 characters gives roughly 342 pixel height. // This is not perfect, but it's usually ok. $length = strlen($link['title']) + 342 * strlen($link['description']) / 836; if ($link['thumbnail']) { $length += 100; } // 1 thumbnails roughly takes 100 pixels height. // Then put in column which is the less filled: $smallest = min($fill); // find smallest value in array. $index = array_search($smallest, $fill); // find index of this smallest value. array_push($columns[$index], $link); // Put entry in this column. $fill[$index] += $length; } $PAGE = new pageBuilder(); $PAGE->assign('linksToDisplay', $linksToDisplay); $PAGE->assign('col1', $columns[0]); $PAGE->assign('col2', $columns[1]); $PAGE->assign('col3', $columns[2]); $PAGE->assign('month', utf8_encode(strftime('%B %Y', linkdate2timestamp($month . '01_000000')))); $PAGE->assign('previousmonth', $previousmonth); $PAGE->assign('nextmonth', $nextmonth); $PAGE->renderPage('monthly'); exit; } // -------- Handle other actions allowed for non-logged in users: if (!isLoggedIn()) { // User tries to post new link but is not loggedin: // Show login screen, then redirect to ?post=... if (isset($_GET['post'])) { header('Location: ?do=login&post=' . urlencode($_GET['post']) . (!empty($_GET['title']) ? '&title=' . urlencode($_GET['title']) : '') . (!empty($_GET['source']) ? '&source=' . urlencode($_GET['source']) : '')); // Redirect to login page, then back to post link. exit; } $PAGE = new pageBuilder(); buildLinkList($PAGE, $LINKSDB); // Compute list of links to display $PAGE->renderPage('linklist'); exit; // Never remove this one ! All operations below are reserved for logged in user. } // -------- All other functions are reserved for the registered user: // -------- Display the Tools menu if requested (import/export/bookmarklet...) if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"], 'do=tools')) { $PAGE = new pageBuilder(); $PAGE->assign('linkcount', count($LINKSDB)); $PAGE->assign('pageabsaddr', indexUrl()); $PAGE->renderPage('tools'); exit; } // -------- User wants to change his/her password. if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"], 'do=changepasswd')) { if ($GLOBALS['config']['OPEN_SHAARLI']) { die('You are not supposed to change a password on an Open Shaarli.'); } if (!empty($_POST['setpassword']) && !empty($_POST['oldpassword'])) { if (!tokenOk($_POST['token'])) { die('Wrong token.'); } // Go away ! // Make sure old password is correct. $oldhash = sha1($_POST['oldpassword'] . $GLOBALS['login'] . $GLOBALS['salt']); if ($oldhash != $GLOBALS['hash']) { echo '<script language="JavaScript">alert("The old password is not correct.");document.location=\'?do=changepasswd\';</script>'; exit; } // Save new password $GLOBALS['salt'] = sha1(uniqid('', true) . '_' . mt_rand()); // Salt renders rainbow-tables attacks useless. $GLOBALS['hash'] = sha1($_POST['setpassword'] . $GLOBALS['login'] . $GLOBALS['salt']); writeConfig(); echo '<script language="JavaScript">alert("Your password has been changed.");document.location=\'?do=tools\';</script>'; exit; } else { $PAGE = new pageBuilder(); $PAGE->assign('linkcount', count($LINKSDB)); $PAGE->assign('token', getToken()); $PAGE->renderPage('changepassword'); exit; } } // -------- User wants to change configuration if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"], 'do=configure')) { if (!empty($_POST['title'])) { if (!tokenOk($_POST['token'])) { die('Wrong token.'); } // Go away ! $tz = 'UTC'; if (!empty($_POST['continent']) && !empty($_POST['city'])) { if (isTZvalid($_POST['continent'], $_POST['city'])) { $tz = $_POST['continent'] . '/' . $_POST['city']; } } $GLOBALS['timezone'] = $tz; $GLOBALS['title'] = $_POST['title']; $GLOBALS['redirector'] = $_POST['redirector']; $GLOBALS['disablesessionprotection'] = !empty($_POST['disablesessionprotection']); writeConfig(); echo '<script language="JavaScript">alert("Configuration was saved.");document.location=\'?do=tools\';</script>'; exit; } else { $PAGE = new pageBuilder(); $PAGE->assign('linkcount', count($LINKSDB)); $PAGE->assign('token', getToken()); $PAGE->assign('title', htmlspecialchars(empty($GLOBALS['title']) ? '' : $GLOBALS['title'], ENT_QUOTES)); $PAGE->assign('redirector', htmlspecialchars(empty($GLOBALS['redirector']) ? '' : $GLOBALS['redirector'], ENT_QUOTES)); list($timezone_form, $timezone_js) = templateTZform($GLOBALS['timezone']); $PAGE->assign('timezone_form', $timezone_form); // FIXME: put entire tz form generation in template ? $PAGE->assign('timezone_js', $timezone_js); $PAGE->renderPage('configure'); exit; } } // -------- User wants to rename a tag or delete it if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"], 'do=changetag')) { if (empty($_POST['fromtag'])) { $PAGE = new pageBuilder(); $PAGE->assign('linkcount', count($LINKSDB)); $PAGE->assign('token', getToken()); $PAGE->renderPage('changetag'); exit; } if (!tokenOk($_POST['token'])) { die('Wrong token.'); } // Delete a tag: if (!empty($_POST['deletetag']) && !empty($_POST['fromtag'])) { $needle = trim($_POST['fromtag']); $linksToAlter = $LINKSDB->filterTags($needle, true); // true for case-sensitive tag search. foreach ($linksToAlter as $key => $value) { $tags = explode(' ', trim($value['tags'])); unset($tags[array_search($needle, $tags)]); // Remove tag. $value['tags'] = trim(implode(' ', $tags)); $LINKSDB[$key] = $value; } $LINKSDB->savedb(); // save to disk echo '<script language="JavaScript">alert("Tag was removed from ' . count($linksToAlter) . ' links.");document.location=\'?\';</script>'; exit; } // Rename a tag: if (!empty($_POST['renametag']) && !empty($_POST['fromtag']) && !empty($_POST['totag'])) { $needle = trim($_POST['fromtag']); $linksToAlter = $LINKSDB->filterTags($needle, true); // true for case-sensitive tag search. foreach ($linksToAlter as $key => $value) { $tags = explode(' ', trim($value['tags'])); $tags[array_search($needle, $tags)] = trim($_POST['totag']); // Remplace tags value. $value['tags'] = trim(implode(' ', $tags)); $LINKSDB[$key] = $value; } $LINKSDB->savedb(); // save to disk echo '<script language="JavaScript">alert("Tag was renamed in ' . count($linksToAlter) . ' links.");document.location=\'?searchtags=' . urlencode($_POST['totag']) . '\';</script>'; exit; } } // -------- User wants to add a link without using the bookmarklet: show form. if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"], 'do=addlink')) { $PAGE = new pageBuilder(); $PAGE->assign('linkcount', count($LINKSDB)); $PAGE->renderPage('addlink'); exit; } // -------- User clicked the "Save" button when editing a link: Save link to database. if (isset($_POST['save_edit'])) { if (!tokenOk($_POST['token'])) { die('Wrong token.'); } // Go away ! $tags = trim(preg_replace('/\\s\\s+/', ' ', $_POST['lf_tags'])); // Remove multiple spaces. $linkdate = $_POST['lf_linkdate']; $link = array('title' => trim($_POST['lf_title']), 'url' => trim($_POST['lf_url']), 'description' => trim($_POST['lf_description']), 'private' => isset($_POST['lf_private']) ? 1 : 0, 'linkdate' => $linkdate, 'tags' => str_replace(',', ' ', $tags)); if ($link['title'] == '') { $link['title'] = $link['url']; } // If title is empty, use the URL as title. $LINKSDB[$linkdate] = $link; $LINKSDB->savedb(); // save to disk pubsubhub(); // If we are called from the bookmarklet, we must close the popup: if (isset($_GET['source']) && $_GET['source'] == 'bookmarklet') { echo '<script language="JavaScript">self.close();</script>'; exit; } $returnurl = isset($_POST['returnurl']) ? $_POST['returnurl'] : '?'; header('Location: ' . $returnurl); // After saving the link, redirect to the page the user was on. exit; } // -------- User clicked the "Cancel" button when editing a link. if (isset($_POST['cancel_edit'])) { // If we are called from the bookmarklet, we must close the popup; if (isset($_GET['source']) && $_GET['source'] == 'bookmarklet') { echo '<script language="JavaScript">self.close();</script>'; exit; } $returnurl = isset($_POST['returnurl']) ? $_POST['returnurl'] : '?'; header('Location: ' . $returnurl); // After canceling, redirect to the page the user was on. exit; } // -------- User clicked the "Delete" button when editing a link : Delete link from database. if (isset($_POST['delete_link'])) { if (!tokenOk($_POST['token'])) { die('Wrong token.'); } // We do not need to ask for confirmation: // - confirmation is handled by javascript // - we are protected from XSRF by the token. $linkdate = $_POST['lf_linkdate']; unset($LINKSDB[$linkdate]); $LINKSDB->savedb(); // save to disk // If we are called from the bookmarklet, we must close the popup: if (isset($_GET['source']) && $_GET['source'] == 'bookmarklet') { echo '<script language="JavaScript">self.close();</script>'; exit; } $returnurl = isset($_POST['returnurl']) ? $_POST['returnurl'] : '?'; if ($returnurl == '?') { $returnurl = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '?'; } header('Location: ' . $returnurl); // After deleting the link, redirect to the page the user was on. exit; } // -------- User clicked the "EDIT" button on a link: Display link edit form. if (isset($_GET['edit_link'])) { $link = $LINKSDB[$_GET['edit_link']]; // Read database if (!$link) { header('Location: ?'); exit; } // Link not found in database. $PAGE = new pageBuilder(); $PAGE->assign('linkcount', count($LINKSDB)); $PAGE->assign('link', $link); $PAGE->assign('link_is_new', false); $PAGE->assign('token', getToken()); // XSRF protection. $PAGE->assign('http_referer', isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ''); $PAGE->renderPage('editlink'); exit; } // -------- User want to post a new link: Display link edit form. if (isset($_GET['post'])) { $url = $_GET['post']; // We remove the annoying parameters added by FeedBurner and GoogleFeedProxy (?utm_source=...) $i = strpos($url, '&utm_source='); if ($i !== false) { $url = substr($url, 0, $i); } $i = strpos($url, '?utm_source='); if ($i !== false) { $url = substr($url, 0, $i); } $i = strpos($url, '#xtor=RSS-'); if ($i !== false) { $url = substr($url, 0, $i); } $link_is_new = false; $link = $LINKSDB->getLinkFromUrl($url); // Check if URL is not already in database (in this case, we will edit the existing link) if (!$link) { $link_is_new = true; // This is a new link $linkdate = strval(date('Ymd_His')); $title = empty($_GET['title']) ? '' : $_GET['title']; // Get title if it was provided in URL (by the bookmarklet). $description = ''; $tags = ''; $private = 0; if ($url != '' && parse_url($url, PHP_URL_SCHEME) == '') { $url = 'http://' . $url; } // If this is an HTTP link, we try go get the page to extact the title (otherwise we will to straight to the edit form.) if (empty($title) && parse_url($url, PHP_URL_SCHEME) == 'http') { list($status, $headers, $data) = getHTTP($url, 4); // Short timeout to keep the application responsive. // FIXME: Decode charset according to specified in either 1) HTTP response headers or 2) <head> in html if (strpos($status, '200 OK') !== false) { $title = html_entity_decode(html_extract_title($data), ENT_QUOTES, 'UTF-8'); } } if ($url == '') { $url = '?' . smallHash($linkdate); } // In case of empty URL, this is just a text (with a link that point to itself) $link = array('linkdate' => $linkdate, 'title' => $title, 'url' => $url, 'description' => $description, 'tags' => $tags, 'private' => 0); } $PAGE = new pageBuilder(); $PAGE->assign('linkcount', count($LINKSDB)); $PAGE->assign('link', $link); $PAGE->assign('link_is_new', $link_is_new); $PAGE->assign('token', getToken()); // XSRF protection. $PAGE->assign('http_referer', isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ''); $PAGE->renderPage('editlink'); exit; } // -------- Export as Netscape Bookmarks HTML file. if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"], 'do=export')) { if (empty($_GET['what'])) { $PAGE = new pageBuilder(); $PAGE->assign('linkcount', count($LINKSDB)); $PAGE->renderPage('export'); exit; } $exportWhat = $_GET['what']; if (!array_intersect(array('all', 'public', 'private'), array($exportWhat))) { die('What are you trying to export ???'); } header('Content-Type: text/html; charset=utf-8'); header('Content-disposition: attachment; filename=bookmarks_' . $exportWhat . '_' . strval(date('Ymd_His')) . '.html'); $currentdate = date('Y/m/d H:i:s'); echo <<<HTML <!DOCTYPE NETSCAPE-Bookmark-file-1> <!-- This is an automatically generated file. It will be read and overwritten. DO NOT EDIT! --> <!-- Shaarli {$exportWhat} bookmarks export on {$currentdate} --> <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8"> <TITLE>Bookmarks</TITLE> <H1>Bookmarks</H1> HTML; foreach ($LINKSDB as $link) { if ($exportWhat == 'all' || $exportWhat == 'private' && $link['private'] != 0 || $exportWhat == 'public' && $link['private'] == 0) { echo '<DT><A HREF="' . htmlspecialchars($link['url']) . '" ADD_DATE="' . linkdate2timestamp($link['linkdate']) . '" PRIVATE="' . $link['private'] . '"'; if ($link['tags'] != '') { echo ' TAGS="' . htmlspecialchars(str_replace(' ', ',', $link['tags'])) . '"'; } echo '>' . htmlspecialchars($link['title']) . "</A>\n"; if ($link['description'] != '') { echo '<DD>' . htmlspecialchars($link['description']) . "\n"; } } } exit; } // -------- User is uploading a file for import if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"], 'do=upload')) { // If file is too big, some form field may be missing. if (!isset($_POST['token']) || !isset($_FILES) || isset($_FILES['filetoupload']['size']) && $_FILES['filetoupload']['size'] == 0) { $returnurl = empty($_SERVER['HTTP_REFERER']) ? '?' : $_SERVER['HTTP_REFERER']; echo '<script language="JavaScript">alert("The file you are trying to upload is probably bigger than what this webserver can accept (' . getMaxFileSize() . ' bytes). Please upload in smaller chunks.");document.location=\'' . htmlspecialchars($returnurl) . '\';</script>'; exit; } if (!tokenOk($_POST['token'])) { die('Wrong token.'); } importFile(); exit; } // -------- Show upload/import dialog: if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"], 'do=import')) { $PAGE = new pageBuilder(); $PAGE->assign('linkcount', count($LINKSDB)); $PAGE->assign('token', getToken()); $PAGE->assign('maxfilesize', getMaxFileSize()); $PAGE->renderPage('import'); exit; } // -------- Otherwise, simply display search form and links: $PAGE = new pageBuilder(); $PAGE->assign('linkcount', count($LINKSDB)); buildLinkList($PAGE, $LINKSDB); // Compute list of links to display $PAGE->renderPage('linklist'); exit; }
function _getMessageParts($message, &$parts) { if (!$message->isMultipart()) { $res = preg_match('/([\\w ]+)\\/([\\w.-]+);.*/', $message->contentType, $matches); if ($matches[1] == 'text' && $matches[2] == 'plain') { $text = $parts['text'] = mb_convert_encoding(quoted_printable_decode($message->getContent()), 'UTF-8'); // convert any windows line endings to unix $text = str_replace("\r\n", "\n", $text); // convert any Classic Mac line endings to Unix $text = str_replace("\r", "\n", $text); // break it into lines $lines = explode("\n", $text); $shortDescLines = array(); foreach ($lines as $line) { if (trim($line)) { $shortDescLines[] = $line; } if (count($shortDescLines) == 3) { break; } } $parts['short'] = implode("\n", $shortDescLines); } else { if ($matches[1] == 'text' && $matches[2] == 'html') { $parts['html'] = mb_convert_encoding(quoted_printable_decode($message->getContent()), 'UTF-8'); } else { $info = importFile($message); $parts['attachments'][] = $info; // print_r($parts); } } return; } foreach ($message as $part) { _getMessageParts($part, $parts); } }
} $total++; } // Walk directory for the second time. This time, encountered // files (and pages contained therein) are imported for real. rewinddir($dh); while (($file = readdir($dh)) !== false) { if ($file == "." || $file == "..") { continue; } if (!importFile($_REQUEST['path'] . "/{$file}")) { pieError("ImportError", array('page' => htmlspecialchars($file))); } $count++; } } elseif (is_readable($_REQUEST['path'])) { // Just one file is to be imported. if (!importFile($_REQUEST['path'])) { pieError("ImportError", array('page' => htmlspecialchars($_REQUEST['path']))); } $total = 1; $count = 1; } // Update the cache. $cache = new Cache(); if ($cache->exists($cache->key('latest', array()))) { $cache->delete($cache->key('latest', array())); } pieLog("alter"); pieNotice("ImportSuccess", array('total' => $total, 'count' => $count)); pieTail();
info("[---------------- starting with {$startWith} ----------------]"); for ($i = $startWith; $i < count($json); $i++) { $candidate = $json[$i]; if ($candidate["EXPLICATIE"]) { continue; } $num = (double) $candidate["college"]; $college_name = ucwords(strtolower("{$candidate["room"]}{$num} {$candidate["county"]}")); addCandidateToCollege($college_name, $candidate["name"], $candidate["party"], $candidate["source"]); $startWith = $i; } } function infoFunction($person, $idString) { return $person->name . ' ' . $idString; } ?> <html> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <body onload="window.scrollTo(0, 1000000);"> <pre> <?php deleteAllContentFirst(); $startWith = (int) $_GET['startWith']; importFile('candidates_2012_bec.json'); include "../_bottom.php"; ?> </pre> </body> </html>
function renderPage() { if (isset($_POST['save_edit'])) { linkdb::$editLink = TRUE; } $LINKSDB = new linkdb(isLoggedIn() || $GLOBALS['config']['OPEN_SHAARLI']); // Read links from database (and filter private links if used it not logged in). // -------- Display login form. if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"], 'do=login')) { if ($GLOBALS['config']['OPEN_SHAARLI']) { header('Location: ?'); exit; } // No need to login for open Shaarli $token = ''; if (ban_canLogin()) { $token = getToken(); } // Do not waste token generation if not useful. $PAGE = new pageBuilder(); $PAGE->assign('token', $token); $PAGE->assign('returnurl', isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ''); $PAGE->renderPage('loginform'); exit; } // -------- User wants to logout. if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"], 'do=logout')) { invalidateCaches(); logout(); header('Location: ?'); exit; } // -------- Picture wall if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"], 'do=picwall')) { // Optionnaly filter the results: $links = array(); if (!empty($_GET['searchterm'])) { $links = $LINKSDB->filterFulltext($_GET['searchterm']); } elseif (!empty($_GET['searchtags'])) { $links = $LINKSDB->filterTags(trim($_GET['searchtags'])); } else { $links = $LINKSDB; } $body = ''; $linksToDisplay = array(); // Get only links which have a thumbnail. foreach ($links as $link) { $permalink = '?' . htmlspecialchars(smallhash($link['linkdate']), ENT_QUOTES); $thumb = lazyThumbnail($link['url'], $permalink); if ($thumb != '') { $link['thumbnail'] = $thumb; // Thumbnail HTML code. $link['permalink'] = $permalink; $linksToDisplay[] = $link; // Add to array. } } $PAGE = new pageBuilder(); $PAGE->assign('linkcount', count($LINKSDB)); $PAGE->assign('linksToDisplay', $linksToDisplay); $PAGE->renderPage('picwall'); exit; } // -------- Tag cloud if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"], 'do=tagcloud')) { $tags = $LINKSDB->allTags(); // We sort tags alphabetically, then choose a font size according to count. // First, find max value. $maxcount = 0; foreach ($tags as $key => $value) { $maxcount = max($maxcount, $value); } ksort($tags); $tagList = array(); foreach ($tags as $key => $value) { $tagList[$key] = array('count' => $value, 'size' => max(40 * $value / $maxcount, 8)); } $PAGE = new pageBuilder(); $PAGE->assign('linkcount', count($LINKSDB)); $PAGE->assign('tags', $tagList); $PAGE->renderPage('tagcloud'); exit; } // -------- User clicks on a tag in a link: The tag is added to the list of searched tags (searchtags=...) if (isset($_GET['addtag'])) { // Get previous URL (http_referer) and add the tag to the searchtags parameters in query. if (empty($_SERVER['HTTP_REFERER'])) { header('Location: ?searchtags=' . urlencode($_GET['addtag'])); exit; } // In case browser does not send HTTP_REFERER parse_str(parse_url($_SERVER['HTTP_REFERER'], PHP_URL_QUERY), $params); $params['searchtags'] = empty($params['searchtags']) ? trim($_GET['addtag']) : trim($params['searchtags']) . ' ' . trim($_GET['addtag']); unset($params['page']); // We also remove page (keeping the same page has no sense, since the results are different) header('Location: ?' . http_build_query($params)); exit; } // -------- User clicks on a tag in result count: Remove the tag from the list of searched tags (searchtags=...) if (isset($_GET['removetag'])) { // Get previous URL (http_referer) and remove the tag from the searchtags parameters in query. if (empty($_SERVER['HTTP_REFERER'])) { header('Location: ?'); exit; } // In case browser does not send HTTP_REFERER parse_str(parse_url($_SERVER['HTTP_REFERER'], PHP_URL_QUERY), $params); if (isset($params['searchtags'])) { $tags = explode(' ', $params['searchtags']); $tags = array_diff($tags, array($_GET['removetag'])); // Remove value from array $tags. if (count($tags) == 0) { unset($params['searchtags']); } else { $params['searchtags'] = implode(' ', $tags); } unset($params['page']); // We also remove page (keeping the same page has no sense, since the results are different) } header('Location: ?' . http_build_query($params)); exit; } // -------- User wants to change the number of links per page (linksperpage=...) if (isset($_GET['linksperpage'])) { if (is_numeric($_GET['linksperpage'])) { $_SESSION['LINKS_PER_PAGE'] = abs(intval($_GET['linksperpage'])); } // Make sure the referer is from Shaarli itself. $referer = '?'; if (!empty($_SERVER['HTTP_REFERER']) && strcmp(parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST), $_SERVER['SERVER_NAME']) == 0) { $referer = $_SERVER['HTTP_REFERER']; } header('Location: ' . $referer); exit; } // -------- User wants to see only private links (toggle) if (isset($_GET['privateonly'])) { if (empty($_SESSION['privateonly'])) { $_SESSION['privateonly'] = 1; // See only private links } else { unset($_SESSION['privateonly']); // See all links } // Make sure the referer is from Shaarli itself. $referer = '?'; if (!empty($_SERVER['HTTP_REFERER']) && strcmp(parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST), $_SERVER['SERVER_NAME']) == 0) { $referer = $_SERVER['HTTP_REFERER']; } header('Location: ' . $referer); exit; } // -------- Handle other actions allowed for non-logged in users: if (!isLoggedIn()) { // User tries to post new link but is not loggedin: // Show login screen, then redirect to ?post=... if (isset($_GET['post'])) { header('Location: ?do=login&post=' . urlencode($_GET['post']) . (!empty($_GET['title']) ? '&title=' . urlencode($_GET['title']) : '') . (!empty($_GET['source']) ? '&source=' . urlencode($_GET['source']) : '')); // Redirect to login page, then back to post link. exit; } $PAGE = new pageBuilder(); buildLinkList($PAGE, $LINKSDB); // Compute list of links to display $PAGE->renderPage('linklist'); exit; // Never remove this one ! All operations below are reserved for logged in user. } // -------- All other functions are reserved for the registered user: // -------- Display the Tools menu if requested (import/export/bookmarklet...) if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"], 'do=tools')) { $PAGE = new pageBuilder(); $PAGE->assign('linkcount', count($LINKSDB)); $PAGE->assign('pageabsaddr', indexUrl()); $PAGE->renderPage('tools'); exit; } // -------- User wants to change his/her password. if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"], 'do=changepasswd')) { if ($GLOBALS['config']['OPEN_SHAARLI']) { die('You are not supposed to change a password on an Open Shaarli.'); } if (!empty($_POST['setpassword']) && !empty($_POST['oldpassword'])) { if (!tokenOk($_POST['token'])) { die('Wrong token.'); } // Go away ! // Make sure old password is correct. $oldhash = sha1($_POST['oldpassword'] . $_SESSION['username'] . $GLOBALS['salt']); if ($oldhash != $GLOBALS['password'][$_SESSION['username']]) { echo '<script language="JavaScript">alert("The old password is not correct.");document.location=\'?do=changepasswd\';</script>'; exit; } // Save new password //$GLOBALS['salt'] = sha1(uniqid('',true).'_'.mt_rand()); // Salt renders rainbow-tables attacks useless. $GLOBALS['password'][$_SESSION['username']] = sha1($_POST['setpassword'] . $_SESSION['username'] . $GLOBALS['salt']); writeConfig(); echo '<script language="JavaScript">alert("Your password has been changed.");document.location=\'?do=tools\';</script>'; exit; } else { $PAGE = new pageBuilder(); $PAGE->assign('linkcount', count($LINKSDB)); $PAGE->assign('token', getToken()); $PAGE->renderPage('changepassword'); exit; } } // -------- User wants to manage users. if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"], 'do=users')) { $PAGE = new pageBuilder(); foreach ($GLOBALS['login'] as $key => $username) { if ($key === 0) { $users[$key]['sysAdmin'] = TRUE; } else { $users[$key]['sysAdmin'] = FALSE; } $users[$key]['username'] = $username; $users[$key]['level'] = $GLOBALS['level'][$username]; $users[$key]['email'] = $GLOBALS['email'][$username]; } $PAGE->assign('users', $users); $PAGE->renderPage('manageusers'); exit; } // -------- Create / Editing user. if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"], 'do=saveUser')) { $saveUserMessage = 'user successfully updated !'; if (isset($_GET['deleteUser'])) { if (is_array($GLOBALS['login'])) { if (in_array($_GET['username'], $GLOBALS['login'])) { $sUkey = array_search($_GET['username'], $GLOBALS['login']); if ($sUkey !== 0) { unset($GLOBALS['login'][$sUkey], $GLOBALS['password'][$_GET['username']], $GLOBALS['level'][$_GET['username']], $GLOBALS['email'][$_GET['username']]); $GLOBALS['login'] = array_values($GLOBALS['login']); writeConfig(); echo '<script language="JavaScript">alert("' . $_GET['username'] . ' was deleted.");document.location=\'?do=users\';</script>'; } } } exit; } if (is_array($GLOBALS['login'])) { if (!in_array($_GET['username'], $GLOBALS['login'])) { $newUserKey = count($GLOBALS['login']); $newUser = array($newUserKey => $_GET['username']); $GLOBALS['login'] = $GLOBALS['login'] + $newUser; $saveUserMessage = 'user successfully created !'; } if (is_array($newUser) || isset($_GET['resetPassword'])) { $newPassword = smallHash(sha1(uniqid('', true) . '_' . mt_rand())); $GLOBALS['password'][$_GET['username']] = sha1($newPassword . $_GET['username'] . $GLOBALS['salt']); $saveUserMessage .= ' His new password is ' . $newPassword; } $GLOBALS['level'][$_GET['username']] = (int) $_GET['userlevel']; $GLOBALS['email'][$_GET['username']] = $_GET['email']; } writeConfig(); echo '<script language="JavaScript">alert("' . $saveUserMessage . '");document.location=\'?do=users\';</script>'; exit; } // -------- User wants to change configuration if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"], 'do=configure')) { if (!empty($_POST['title'])) { if (!tokenOk($_POST['token'])) { die('Wrong token.'); } // Go away ! $tz = 'UTC'; if (!empty($_POST['continent']) && !empty($_POST['city'])) { if (isTZvalid($_POST['continent'], $_POST['city'])) { $tz = $_POST['continent'] . '/' . $_POST['city']; } } $GLOBALS['timezone'] = $tz; $GLOBALS['title'] = $_POST['title']; $GLOBALS['redirector'] = $_POST['redirector']; $GLOBALS['disablesessionprotection'] = !empty($_POST['disablesessionprotection']); $GLOBALS['disablejquery'] = !empty($_POST['disablejquery']); $GLOBALS['privateLinkByDefault'] = !empty($_POST['privateLinkByDefault']); writeConfig(); echo '<script language="JavaScript">alert("Configuration was saved.");document.location=\'?do=tools\';</script>'; exit; } else { $PAGE = new pageBuilder(); $PAGE->assign('linkcount', count($LINKSDB)); $PAGE->assign('token', getToken()); $PAGE->assign('title', htmlspecialchars(empty($GLOBALS['title']) ? '' : $GLOBALS['title'], ENT_QUOTES)); $PAGE->assign('redirector', htmlspecialchars(empty($GLOBALS['redirector']) ? '' : $GLOBALS['redirector'], ENT_QUOTES)); list($timezone_form, $timezone_js) = templateTZform($GLOBALS['timezone']); $PAGE->assign('timezone_form', $timezone_form); // FIXME: put entire tz form generation in template ? $PAGE->assign('timezone_js', $timezone_js); $PAGE->renderPage('configure'); exit; } } // -------- User wants to rename a tag or delete it if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"], 'do=changetag')) { if (empty($_POST['fromtag'])) { $PAGE = new pageBuilder(); $PAGE->assign('linkcount', count($LINKSDB)); $PAGE->assign('token', getToken()); $PAGE->renderPage('changetag'); exit; } if (!tokenOk($_POST['token'])) { die('Wrong token.'); } // Delete a tag: if (!empty($_POST['deletetag']) && !empty($_POST['fromtag'])) { $needle = trim($_POST['fromtag']); $linksToAlter = $LINKSDB->filterTags($needle, true); // true for case-sensitive tag search. foreach ($linksToAlter as $key => $value) { $tags = explode(' ', trim($value['tags'])); unset($tags[array_search($needle, $tags)]); // Remove tag. $value['tags'] = trim(implode(' ', $tags)); $LINKSDB[$key] = $value; } $LINKSDB->savedb(); // save to disk echo '<script language="JavaScript">alert("Tag was removed from ' . count($linksToAlter) . ' links.");document.location=\'?\';</script>'; exit; } // Rename a tag: if (!empty($_POST['renametag']) && !empty($_POST['fromtag']) && !empty($_POST['totag'])) { $needle = trim($_POST['fromtag']); $linksToAlter = $LINKSDB->filterTags($needle, true); // true for case-sensitive tag search. foreach ($linksToAlter as $key => $value) { $tags = explode(' ', trim($value['tags'])); $tags[array_search($needle, $tags)] = trim($_POST['totag']); // Remplace tags value. $value['tags'] = trim(implode(' ', $tags)); $LINKSDB[$key] = $value; } $LINKSDB->savedb(); // save to disk echo '<script language="JavaScript">alert("Tag was renamed in ' . count($linksToAlter) . ' links.");document.location=\'?searchtags=' . urlencode($_POST['totag']) . '\';</script>'; exit; } } // -------- User wants to add a link without using the bookmarklet: show form. if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"], 'do=addlink')) { $PAGE = new pageBuilder(); $PAGE->assign('linkcount', count($LINKSDB)); $PAGE->renderPage('addlink'); exit; } // -------- User clicked the "Save" button when editing a link: Save link to database. if (isset($_POST['save_edit'])) { if (!tokenOk($_POST['token'])) { die('Wrong token.'); } // Go away ! $tags = trim(preg_replace('/\\s\\s+/', ' ', $_POST['lf_tags'])); // Remove multiple spaces. $linkdate = $_POST['lf_linkdate']; // If user is not an admin and try to edit other link of him and keep author when updating link if (isset($LINKSDB[$linkdate])) { if ($_SESSION['level'] < 3 && $LINKSDB[$linkdate]['author'] !== $_SESSION['username']) { die('You cannot edit link of other !'); } $author = $LINKSDB[$linkdate]['author']; } else { $author = $_SESSION['username']; } $url = trim($_POST['lf_url']); if (!startsWith($url, 'http:') && !startsWith($url, 'https:') && !startsWith($url, 'ftp:') && !startsWith($url, 'magnet:') && !startsWith($url, '?')) { $url = 'http://' . $url; } $link = array('title' => trim($_POST['lf_title']), 'url' => $url, 'description' => trim($_POST['lf_description']), 'private' => $_POST['lf_private'], 'author' => $author, 'linkdate' => $linkdate, 'tags' => str_replace(',', ' ', $tags)); if ($link['title'] == '') { $link['title'] = $link['url']; } // If title is empty, use the URL as title. $LINKSDB[$linkdate] = $link; $LINKSDB->savedb(); // save to disk pubsubhub(); // If we are called from the bookmarklet, we must close the popup: if (isset($_GET['source']) && $_GET['source'] == 'bookmarklet') { echo '<script language="JavaScript">self.close();</script>'; exit; } $returnurl = isset($_POST['returnurl']) ? $_POST['returnurl'] : '?'; $returnurl .= '#' . smallHash($linkdate); // Scroll to the link which has been edited. header('Location: ' . $returnurl); // After saving the link, redirect to the page the user was on. exit; } // -------- User clicked the "Cancel" button when editing a link. if (isset($_POST['cancel_edit'])) { // If we are called from the bookmarklet, we must close the popup; if (isset($_GET['source']) && $_GET['source'] == 'bookmarklet') { echo '<script language="JavaScript">self.close();</script>'; exit; } $returnurl = isset($_POST['returnurl']) ? $_POST['returnurl'] : '?'; $returnurl .= '#' . smallHash($_POST['lf_linkdate']); // Scroll to the link which has been edited. header('Location: ' . $returnurl); // After canceling, redirect to the page the user was on. exit; } // -------- User clicked the "Delete" button when editing a link : Delete link from database. if (isset($_POST['delete_link'])) { if (!tokenOk($_POST['token'])) { die('Wrong token.'); } // We do not need to ask for confirmation: // - confirmation is handled by javascript // - we are protected from XSRF by the token. $linkdate = $_POST['lf_linkdate']; if ($_SESSION['level'] < 3 && $LINKSDB[$linkdate]['author'] !== $_SESSION['username']) { die('You cannot delete link of other !'); } unset($LINKSDB[$linkdate]); $LINKSDB->savedb(); // save to disk // If we are called from the bookmarklet, we must close the popup: if (isset($_GET['source']) && $_GET['source'] == 'bookmarklet') { echo '<script language="JavaScript">self.close();</script>'; exit; } $returnurl = isset($_POST['returnurl']) ? $_POST['returnurl'] : '?'; if ($returnurl == '?') { $returnurl = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '?'; } header('Location: ' . $returnurl); // After deleting the link, redirect to the page the user was on. exit; } // -------- User clicked the "EDIT" button on a link: Display link edit form. if (isset($_GET['edit_link'])) { $link = $LINKSDB[$_GET['edit_link']]; // Read database if (!$link) { header('Location: ?'); exit; } // Link not found in database. if ($_SESSION['level'] < 3 && $LINKSDB[$_GET['edit_link']]['author'] !== $_SESSION['username']) { exit; } // If user is not an admin and try to edit other link of him $PAGE = new pageBuilder(); $PAGE->assign('linkcount', count($LINKSDB)); $PAGE->assign('link', $link); $PAGE->assign('link_is_new', false); $PAGE->assign('token', getToken()); // XSRF protection. $PAGE->assign('http_referer', isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ''); $PAGE->renderPage('editlink'); exit; } // -------- User want to post a new link: Display link edit form. if (isset($_GET['post'])) { $url = $_GET['post']; // We remove the annoying parameters added by FeedBurner and GoogleFeedProxy (?utm_source=...) $i = strpos($url, '&utm_source='); if ($i !== false) { $url = substr($url, 0, $i); } $i = strpos($url, '?utm_source='); if ($i !== false) { $url = substr($url, 0, $i); } $i = strpos($url, '#xtor=RSS-'); if ($i !== false) { $url = substr($url, 0, $i); } $link_is_new = false; $link = $LINKSDB->getLinkFromUrl($url); // Check if URL is not already in database (in this case, we will edit the existing link) if (!$link) { $link_is_new = true; // This is a new link $linkdate = strval(date('Ymd_His')); $title = empty($_GET['title']) ? '' : $_GET['title']; // Get title if it was provided in URL (by the bookmarklet). $description = ''; $tags = ''; $private = 2; $author = $_SESSION['username']; if ($url != '' && parse_url($url, PHP_URL_SCHEME) == '') { $url = 'http://' . $url; } // If this is an HTTP link, we try go get the page to extact the title (otherwise we will to straight to the edit form.) if (empty($title) && parse_url($url, PHP_URL_SCHEME) == 'http') { list($status, $headers, $data) = getHTTP($url, 4); // Short timeout to keep the application responsive. // FIXME: Decode charset according to specified in either 1) HTTP response headers or 2) <head> in html if (strpos($status, '200 OK') !== false) { $title = html_entity_decode(html_extract_title($data), ENT_QUOTES, 'UTF-8'); } } if ($url == '') { $url = '?' . smallHash($linkdate); } // In case of empty URL, this is just a text (with a link that point to itself) $link = array('linkdate' => $linkdate, 'title' => $title, 'url' => $url, 'description' => $description, 'tags' => $tags, 'private' => 2, 'author' => $author); } $PAGE = new pageBuilder(); $PAGE->assign('linkcount', count($LINKSDB)); $PAGE->assign('link', $link); $PAGE->assign('link_is_new', $link_is_new); $PAGE->assign('token', getToken()); // XSRF protection. $PAGE->assign('http_referer', isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ''); $PAGE->renderPage('editlink'); exit; } // -------- Export as Netscape Bookmarks HTML file. if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"], 'do=export')) { if (empty($_GET['what'])) { $PAGE = new pageBuilder(); $PAGE->assign('linkcount', count($LINKSDB)); $PAGE->renderPage('export'); exit; } $exportWhat = $_GET['what']; if (!array_intersect(array('all', 'public', 'private'), array($exportWhat))) { die('What are you trying to export ???'); } header('Content-Type: text/html; charset=utf-8'); header('Content-disposition: attachment; filename=bookmarks_' . $exportWhat . '_' . strval(date('Ymd_His')) . '.html'); $currentdate = date('Y/m/d H:i:s'); echo <<<HTML <!DOCTYPE NETSCAPE-Bookmark-file-1> <!-- This is an automatically generated file. It will be read and overwritten. DO NOT EDIT! --> <!-- Shaarli {$exportWhat} bookmarks export on {$currentdate} --> <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8"> <TITLE>Bookmarks</TITLE> <H1>Bookmarks</H1> HTML; foreach ($LINKSDB as $link) { if ($exportWhat == 'all' || $exportWhat == 'private' && $link['private'] != 0 || $exportWhat == 'public' && $link['private'] == 0) { echo '<DT><A HREF="' . htmlspecialchars($link['url']) . '" ADD_DATE="' . linkdate2timestamp($link['linkdate']) . '" PRIVATE="' . $link['private'] . '"'; if ($link['tags'] != '') { echo ' TAGS="' . htmlspecialchars(str_replace(' ', ',', $link['tags'])) . '"'; } echo '>' . htmlspecialchars($link['title']) . "</A>\n"; if ($link['description'] != '') { echo '<DD>' . htmlspecialchars($link['description']) . "\n"; } } } exit; } // -------- User is uploading a file for import if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"], 'do=upload')) { // If file is too big, some form field may be missing. if (!isset($_POST['token']) || !isset($_FILES) || isset($_FILES['filetoupload']['size']) && $_FILES['filetoupload']['size'] == 0) { $returnurl = empty($_SERVER['HTTP_REFERER']) ? '?' : $_SERVER['HTTP_REFERER']; echo '<script language="JavaScript">alert("The file you are trying to upload is probably bigger than what this webserver can accept (' . getMaxFileSize() . ' bytes). Please upload in smaller chunks.");document.location=\'' . htmlspecialchars($returnurl) . '\';</script>'; exit; } if (!tokenOk($_POST['token'])) { die('Wrong token.'); } importFile(); exit; } // -------- Show upload/import dialog: if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"], 'do=import')) { $PAGE = new pageBuilder(); $PAGE->assign('linkcount', count($LINKSDB)); $PAGE->assign('token', getToken()); $PAGE->assign('maxfilesize', getMaxFileSize()); $PAGE->renderPage('import'); exit; } // -------- Otherwise, simply display search form and links: $PAGE = new pageBuilder(); $PAGE->assign('linkcount', count($LINKSDB)); buildLinkList($PAGE, $LINKSDB); // Compute list of links to display $PAGE->renderPage('linklist'); exit; }
# # # # # # # # # # define("CUBIT_IMPORTCOMP", true); require "newsettings.php"; require "psql_path.php"; require_lib("validate"); if (isset($_FILES["compfile"])) { $OUTPUT = importFile(); } else { $OUTPUT = selectFile(); } require "newtemplate.php"; function selectFile() { global $_POST; $newcomp = ""; if (!isset($_SESSION["USER_NAME"])) { $newcomp .= "\n\t\t\t<h3>Browser Notice</h3>\n\t\t\t<b>Cubit requires Firefox 1.5 or later. Click\n\t\t\t<a class='nav' href='MozillaInstall/firefox.exe'>here</a> to install it.</b>"; db_conn('cubit'); $rslt = db_exec("SELECT * FROM companies WHERE status='active'"); if (pg_numrows($rslt) > 0) { header("Location: complogin.php"); }
if ($id > 0) { $ret = $object->fetch($id); if ($ret > 0) { $ret = $object->fetch_thirdparty(); } if ($ret < 0) { dol_print_error('', $object->error); } if ($object->statut != Propal::STATUS_DRAFT || $object->statut != Commande::STATUS_DRAFT) { //var_dump('toto');exit; $error = true; setEventMessages($langs->trans('importdevis' . $origin . 'DraftWarning'), null, 'warnings'); } } if ($action == 'send_file') { $TData = importFile($db, $conf, $langs); fiche_preview($object, $TData); exit; } else { if ($action == 'import_data') { if (!empty($delete_lines_before_import) && !empty($object->lines)) { foreach ($object->lines as $l) { $l->delete(); } } $default_tva = 0; if (!empty($conf->global->IMPORTPROPAL_FORCE_TVA)) { $default_tva = $conf->global->IMPORTPROPAL_FORCE_TVA; } $TLastLevelTitleAdded = array(); // Tableau pour empiler et dépiller les niveaux de titre pour ensuite ajouter les sous-totaux
if (isset($_REQUEST["m"]) && !preg_match("=/=", $_REQUEST["m"])) { switch ($_REQUEST['m']) { case 'facic': $dataModel = new title(); $formatedRecords = displayFacic($dataModel); break; case 'title': $dataModel = new title(); $formatedRecords = displayTitle($dataModel, $_REQUEST["edit"], $_REQUEST["format"]); break; case 'titleplus': $dataModel = new titleplus(); $formatedRecords = displayTitlePlus($dataModel, $_REQUEST["edit"]); break; case 'import': $formatedRecords = importFile(); break; case 'reverseDB': $formatedRecords = reverseDatabase(); break; case 'unlockDB': $formatedRecords = unlockDatabase(); break; case 'report': $dataModel = new title(); $formatedRecords = report($dataModel); break; } } function report($dataModel) {
$person_content = ""; info($matches[1] . ". " . $matches[2]); } else { # This is just content, add it up. $person_content .= $line . "\n"; } } } } addContentToPerson($person_name, $person_context, $person_content, $source); fclose($file_handle); } function infoFunction($person, $idString) { return $person->name . ' ' . $idString; } ?> <html> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <body onload="window.scrollTo(0, 1000000);"> <pre> <?php deleteAllContentFirst(); importFile('romania_curata_1.txt'); importFile('romania_curata_2.txt'); include "../_bottom.php"; ?> </pre> </body> </html>
$other_candidate = trim($other_candidate); if ($other_candidate == "") { continue; } $parts = extractNameAndParty($other_candidate); addCandidateToCollege($college_name, $parts[0], $parts[1]); } $startWith = $i; } } function infoFunction($person, $idString) { return $person->name . ' ' . $idString; } ?> <html> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <body onload="window.scrollTo(0, 1000000);"> <pre> <?php $startWith = (int) $_GET['startWith']; deleteAllContentFirst(); importFile('candidates_2012_senat.json', 'S'); $startWith = 0; importFile('candidates_2012_cdep.json', 'D'); include "../_bottom.php"; ?> </pre> </body> </html>
* @version $Revision: 4983 $ */ CCanDo::checkAdmin(); ini_set("auto_detect_line_endings", true); global $dPconfig; $dPconfig["object_handlers"] = array(); CAppUI::stepAjax("Désactivation du gestionnaire", UI_MSG_OK); $start = CValue::post("start"); $count = CValue::post("count"); $callback = CValue::post("callback"); $date = CMbDT::date(); CApp::setTimeLimit(600); CApp::setMemoryLimit("512M"); CMbObject::$useObjectCache = false; $file_import = fopen(CAppUI::conf("root_dir") . "/tmp/rapport_import_patient_{$date}.txt", "a"); importFile(CAppUI::conf("dPpatients imports pat_csv_path"), $start, $count, $file_import); fclose($file_import); $start += $count; file_put_contents(CAppUI::conf("root_dir") . "/tmp/import_patient.txt", "{$start};{$count}"); if ($callback) { CAppUI::js("{$callback}({$start},{$count})"); } echo "<tr><td colspan=\"2\">MEMORY: " . memory_get_peak_usage(true) / (1024 * 1024) . " MB" . "</td>"; CMbObject::$useObjectCache = true; CApp::rip(); /** * import the patient file * * @param string $file path to the file * @param int $start start int * @param int $count number of iterations
<?php mysql_connect('localhost', 'root'); mysql_select_db('names'); mysql_set_charset('utf8'); function importFile($file, $into) { $names = file($file); foreach ($names as $name) { mysql_query("INSERT INTO {$into} VALUES ('" . trim($name) . "');"); } } importFile('boyname.txt', 'rufirst'); importFile('girlname.txt', 'rufirst'); importFile('girlsirname.txt', 'rusecond'); importFile('boysirname.txt', 'rusecond');
function renderPage() { $LINKSDB = new LinkDB($GLOBALS['config']['DATASTORE'], isLoggedIn(), $GLOBALS['config']['HIDE_PUBLIC_LINKS'], $GLOBALS['redirector']); $PAGE = new pageBuilder(); // Determine which page will be rendered. $query = isset($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : ''; $targetPage = Router::findPage($query, $_GET, isLoggedIn()); // Call plugin hooks for header, footer and includes, specifying which page will be rendered. // Then assign generated data to RainTPL. $common_hooks = array('header', 'footer', 'includes'); $pluginManager = PluginManager::getInstance(); foreach ($common_hooks as $name) { $plugin_data = array(); $pluginManager->executeHooks('render_' . $name, $plugin_data, array('target' => $targetPage, 'loggedin' => isLoggedIn())); $PAGE->assign('plugins_' . $name, $plugin_data); } // -------- Display login form. if ($targetPage == Router::$PAGE_LOGIN) { if ($GLOBALS['config']['OPEN_SHAARLI']) { header('Location: ?'); exit; } // No need to login for open Shaarli $token = ''; if (ban_canLogin()) { $token = getToken(); } // Do not waste token generation if not useful. $PAGE->assign('token', $token); $PAGE->assign('returnurl', isset($_SERVER['HTTP_REFERER']) ? escape($_SERVER['HTTP_REFERER']) : ''); $PAGE->renderPage('loginform'); exit; } // -------- User wants to logout. if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"], 'do=logout')) { invalidateCaches($GLOBALS['config']['PAGECACHE']); logout(); header('Location: ?'); exit; } // -------- Picture wall if ($targetPage == Router::$PAGE_PICWALL) { // Optionally filter the results: if (!empty($_GET['searchterm'])) { $links = $LINKSDB->filter(LinkFilter::$FILTER_TEXT, $_GET['searchterm']); } elseif (!empty($_GET['searchtags'])) { $links = $LINKSDB->filter(LinkFilter::$FILTER_TAG, trim($_GET['searchtags'])); } else { $links = $LINKSDB; } $linksToDisplay = array(); // Get only links which have a thumbnail. foreach ($links as $link) { $permalink = '?' . escape(smallhash($link['linkdate'])); $thumb = lazyThumbnail($link['url'], $permalink); if ($thumb != '') { $link['thumbnail'] = $thumb; // Thumbnail HTML code. $linksToDisplay[] = $link; // Add to array. } } $data = array('linkcount' => count($LINKSDB), 'linksToDisplay' => $linksToDisplay); $pluginManager->executeHooks('render_picwall', $data, array('loggedin' => isLoggedIn())); foreach ($data as $key => $value) { $PAGE->assign($key, $value); } $PAGE->renderPage('picwall'); exit; } // -------- Tag cloud if ($targetPage == Router::$PAGE_TAGCLOUD) { $tags = $LINKSDB->allTags(); // We sort tags alphabetically, then choose a font size according to count. // First, find max value. $maxcount = 0; foreach ($tags as $key => $value) { $maxcount = max($maxcount, $value); } ksort($tags); $tagList = array(); foreach ($tags as $key => $value) { $tagList[$key] = array('count' => $value, 'size' => log($value, 15) / log($maxcount, 30) * (22 - 6) + 6); } $data = array('linkcount' => count($LINKSDB), 'tags' => $tagList); $pluginManager->executeHooks('render_tagcloud', $data, array('loggedin' => isLoggedIn())); foreach ($data as $key => $value) { $PAGE->assign($key, $value); } $PAGE->renderPage('tagcloud'); exit; } // Daily page. if ($targetPage == Router::$PAGE_DAILY) { showDaily($PAGE); } // Display openseach plugin (XML) if ($targetPage == Router::$PAGE_OPENSEARCH) { header('Content-Type: application/xml; charset=utf-8'); $PAGE->assign('serverurl', index_url($_SERVER)); $PAGE->renderPage('opensearch'); exit; } // -------- User clicks on a tag in a link: The tag is added to the list of searched tags (searchtags=...) if (isset($_GET['addtag'])) { // Get previous URL (http_referer) and add the tag to the searchtags parameters in query. if (empty($_SERVER['HTTP_REFERER'])) { header('Location: ?searchtags=' . urlencode($_GET['addtag'])); exit; } // In case browser does not send HTTP_REFERER parse_str(parse_url($_SERVER['HTTP_REFERER'], PHP_URL_QUERY), $params); // Prevent redirection loop if (isset($params['addtag'])) { unset($params['addtag']); } // Check if this tag is already in the search query and ignore it if it is. // Each tag is always separated by a space if (isset($params['searchtags'])) { $current_tags = explode(' ', $params['searchtags']); } else { $current_tags = array(); } $addtag = true; foreach ($current_tags as $value) { if ($value === $_GET['addtag']) { $addtag = false; break; } } // Append the tag if necessary if (empty($params['searchtags'])) { $params['searchtags'] = trim($_GET['addtag']); } else { if ($addtag) { $params['searchtags'] = trim($params['searchtags']) . ' ' . trim($_GET['addtag']); } } unset($params['page']); // We also remove page (keeping the same page has no sense, since the results are different) header('Location: ?' . http_build_query($params)); exit; } // -------- User clicks on a tag in result count: Remove the tag from the list of searched tags (searchtags=...) if (isset($_GET['removetag'])) { // Get previous URL (http_referer) and remove the tag from the searchtags parameters in query. if (empty($_SERVER['HTTP_REFERER'])) { header('Location: ?'); exit; } // In case browser does not send HTTP_REFERER parse_str(parse_url($_SERVER['HTTP_REFERER'], PHP_URL_QUERY), $params); // Prevent redirection loop if (isset($params['removetag'])) { unset($params['removetag']); } if (isset($params['searchtags'])) { $tags = explode(' ', $params['searchtags']); // Remove value from array $tags. $tags = array_diff($tags, array($_GET['removetag'])); $params['searchtags'] = implode(' ', $tags); if (empty($params['searchtags'])) { unset($params['searchtags']); } unset($params['page']); // We also remove page (keeping the same page has no sense, since the results are different) } header('Location: ?' . http_build_query($params)); exit; } // -------- User wants to change the number of links per page (linksperpage=...) if (isset($_GET['linksperpage'])) { if (is_numeric($_GET['linksperpage'])) { $_SESSION['LINKS_PER_PAGE'] = abs(intval($_GET['linksperpage'])); } header('Location: ' . generateLocation($_SERVER['HTTP_REFERER'], $_SERVER['HTTP_HOST'], array('linksperpage'))); exit; } // -------- User wants to see only private links (toggle) if (isset($_GET['privateonly'])) { if (empty($_SESSION['privateonly'])) { $_SESSION['privateonly'] = 1; // See only private links } else { unset($_SESSION['privateonly']); // See all links } header('Location: ' . generateLocation($_SERVER['HTTP_REFERER'], $_SERVER['HTTP_HOST'], array('privateonly'))); exit; } // -------- Handle other actions allowed for non-logged in users: if (!isLoggedIn()) { // User tries to post new link but is not logged in: // Show login screen, then redirect to ?post=... if (isset($_GET['post'])) { header('Location: ?do=login&post=' . urlencode($_GET['post']) . (!empty($_GET['title']) ? '&title=' . urlencode($_GET['title']) : '') . (!empty($_GET['description']) ? '&description=' . urlencode($_GET['description']) : '') . (!empty($_GET['source']) ? '&source=' . urlencode($_GET['source']) : '')); // Redirect to login page, then back to post link. exit; } // Same case as above except that user tried to access ?do=addlink without being logged in // Note: passing empty parameters makes Shaarli generate default URLs and descriptions. if (isset($_GET['do']) && $_GET['do'] === 'addlink') { header('Location: ?do=login&post='); exit; } showLinkList($PAGE, $LINKSDB); if (isset($_GET['edit_link'])) { header('Location: ?do=login&edit_link=' . escape($_GET['edit_link'])); exit; } exit; // Never remove this one! All operations below are reserved for logged in user. } // -------- All other functions are reserved for the registered user: // -------- Display the Tools menu if requested (import/export/bookmarklet...) if ($targetPage == Router::$PAGE_TOOLS) { $data = array('linkcount' => count($LINKSDB), 'pageabsaddr' => index_url($_SERVER)); $pluginManager->executeHooks('render_tools', $data); foreach ($data as $key => $value) { $PAGE->assign($key, $value); } $PAGE->renderPage('tools'); exit; } // -------- User wants to change his/her password. if ($targetPage == Router::$PAGE_CHANGEPASSWORD) { if ($GLOBALS['config']['OPEN_SHAARLI']) { die('You are not supposed to change a password on an Open Shaarli.'); } if (!empty($_POST['setpassword']) && !empty($_POST['oldpassword'])) { if (!tokenOk($_POST['token'])) { die('Wrong token.'); } // Go away! // Make sure old password is correct. $oldhash = sha1($_POST['oldpassword'] . $GLOBALS['login'] . $GLOBALS['salt']); if ($oldhash != $GLOBALS['hash']) { echo '<script>alert("The old password is not correct.");document.location=\'?do=changepasswd\';</script>'; exit; } // Save new password $GLOBALS['salt'] = sha1(uniqid('', true) . '_' . mt_rand()); // Salt renders rainbow-tables attacks useless. $GLOBALS['hash'] = sha1($_POST['setpassword'] . $GLOBALS['login'] . $GLOBALS['salt']); try { writeConfig($GLOBALS, isLoggedIn()); } catch (Exception $e) { error_log('ERROR while writing config file after changing password.' . PHP_EOL . $e->getMessage()); // TODO: do not handle exceptions/errors in JS. echo '<script>alert("' . $e->getMessage() . '");document.location=\'?do=tools\';</script>'; exit; } echo '<script>alert("Your password has been changed.");document.location=\'?do=tools\';</script>'; exit; } else { $PAGE->assign('linkcount', count($LINKSDB)); $PAGE->assign('token', getToken()); $PAGE->renderPage('changepassword'); exit; } } // -------- User wants to change configuration if ($targetPage == Router::$PAGE_CONFIGURE) { if (!empty($_POST['title'])) { if (!tokenOk($_POST['token'])) { die('Wrong token.'); } // Go away! $tz = 'UTC'; if (!empty($_POST['continent']) && !empty($_POST['city'])) { if (isTimeZoneValid($_POST['continent'], $_POST['city'])) { $tz = $_POST['continent'] . '/' . $_POST['city']; } } $GLOBALS['timezone'] = $tz; $GLOBALS['title'] = $_POST['title']; $GLOBALS['titleLink'] = $_POST['titleLink']; $GLOBALS['redirector'] = $_POST['redirector']; $GLOBALS['disablesessionprotection'] = !empty($_POST['disablesessionprotection']); $GLOBALS['privateLinkByDefault'] = !empty($_POST['privateLinkByDefault']); $GLOBALS['config']['ENABLE_RSS_PERMALINKS'] = !empty($_POST['enableRssPermalinks']); $GLOBALS['config']['ENABLE_UPDATECHECK'] = !empty($_POST['updateCheck']); $GLOBALS['config']['HIDE_PUBLIC_LINKS'] = !empty($_POST['hidePublicLinks']); try { writeConfig($GLOBALS, isLoggedIn()); } catch (Exception $e) { error_log('ERROR while writing config file after configuration update.' . PHP_EOL . $e->getMessage()); // TODO: do not handle exceptions/errors in JS. echo '<script>alert("' . $e->getMessage() . '");document.location=\'?do=tools\';</script>'; exit; } echo '<script>alert("Configuration was saved.");document.location=\'?do=tools\';</script>'; exit; } else { $PAGE->assign('linkcount', count($LINKSDB)); $PAGE->assign('token', getToken()); $PAGE->assign('title', empty($GLOBALS['title']) ? '' : $GLOBALS['title']); $PAGE->assign('redirector', empty($GLOBALS['redirector']) ? '' : $GLOBALS['redirector']); list($timezone_form, $timezone_js) = generateTimeZoneForm($GLOBALS['timezone']); $PAGE->assign('timezone_form', $timezone_form); $PAGE->assign('timezone_js', $timezone_js); $PAGE->renderPage('configure'); exit; } } // -------- User wants to rename a tag or delete it if ($targetPage == Router::$PAGE_CHANGETAG) { if (empty($_POST['fromtag']) || empty($_POST['totag']) && isset($_POST['renametag'])) { $PAGE->assign('linkcount', count($LINKSDB)); $PAGE->assign('token', getToken()); $PAGE->assign('tags', $LINKSDB->allTags()); $PAGE->renderPage('changetag'); exit; } if (!tokenOk($_POST['token'])) { die('Wrong token.'); } // Delete a tag: if (isset($_POST['deletetag']) && !empty($_POST['fromtag'])) { $needle = trim($_POST['fromtag']); // True for case-sensitive tag search. $linksToAlter = $LINKSDB->filter(LinkFilter::$FILTER_TAG, $needle, true); foreach ($linksToAlter as $key => $value) { $tags = explode(' ', trim($value['tags'])); unset($tags[array_search($needle, $tags)]); // Remove tag. $value['tags'] = trim(implode(' ', $tags)); $LINKSDB[$key] = $value; } $LINKSDB->savedb($GLOBALS['config']['PAGECACHE']); echo '<script>alert("Tag was removed from ' . count($linksToAlter) . ' links.");document.location=\'?\';</script>'; exit; } // Rename a tag: if (isset($_POST['renametag']) && !empty($_POST['fromtag']) && !empty($_POST['totag'])) { $needle = trim($_POST['fromtag']); // True for case-sensitive tag search. $linksToAlter = $LINKSDB->filter(LinkFilter::$FILTER_TAG, $needle, true); foreach ($linksToAlter as $key => $value) { $tags = explode(' ', trim($value['tags'])); $tags[array_search($needle, $tags)] = trim($_POST['totag']); // Replace tags value. $value['tags'] = trim(implode(' ', $tags)); $LINKSDB[$key] = $value; } $LINKSDB->savedb($GLOBALS['config']['PAGECACHE']); // Save to disk. echo '<script>alert("Tag was renamed in ' . count($linksToAlter) . ' links.");document.location=\'?searchtags=' . urlencode($_POST['totag']) . '\';</script>'; exit; } } // -------- User wants to add a link without using the bookmarklet: Show form. if ($targetPage == Router::$PAGE_ADDLINK) { $PAGE->assign('linkcount', count($LINKSDB)); $PAGE->renderPage('addlink'); exit; } // -------- User clicked the "Save" button when editing a link: Save link to database. if (isset($_POST['save_edit'])) { if (!tokenOk($_POST['token'])) { die('Wrong token.'); } // Go away! $tags = trim(preg_replace('/\\s\\s+/', ' ', $_POST['lf_tags'])); // Remove multiple spaces. $tags = implode(' ', array_unique(explode(' ', $tags))); // Remove duplicates. $linkdate = $_POST['lf_linkdate']; $url = trim($_POST['lf_url']); if (!startsWith($url, 'http:') && !startsWith($url, 'https:') && !startsWith($url, 'ftp:') && !startsWith($url, 'magnet:') && !startsWith($url, '?') && !startsWith($url, 'javascript:')) { $url = 'http://' . $url; } $link = array('title' => trim($_POST['lf_title']), 'url' => $url, 'description' => trim($_POST['lf_description']), 'private' => isset($_POST['lf_private']) ? 1 : 0, 'linkdate' => $linkdate, 'tags' => str_replace(',', ' ', $tags)); if ($link['title'] == '') { $link['title'] = $link['url']; } // If title is empty, use the URL as title. $pluginManager->executeHooks('save_link', $link); $LINKSDB[$linkdate] = $link; $LINKSDB->savedb($GLOBALS['config']['PAGECACHE']); // Save to disk. pubsubhub(); // If we are called from the bookmarklet, we must close the popup: if (isset($_GET['source']) && ($_GET['source'] == 'bookmarklet' || $_GET['source'] == 'firefoxsocialapi')) { echo '<script>self.close();</script>'; exit; } $returnurl = !empty($_POST['returnurl']) ? escape($_POST['returnurl']) : '?'; $location = generateLocation($returnurl, $_SERVER['HTTP_HOST'], array('addlink', 'post', 'edit_link')); $location .= '#' . smallHash($_POST['lf_linkdate']); // Scroll to the link which has been edited. header('Location: ' . $location); // After saving the link, redirect to the page the user was on. exit; } // -------- User clicked the "Cancel" button when editing a link. if (isset($_POST['cancel_edit'])) { // If we are called from the bookmarklet, we must close the popup: if (isset($_GET['source']) && ($_GET['source'] == 'bookmarklet' || $_GET['source'] == 'firefoxsocialapi')) { echo '<script>self.close();</script>'; exit; } $returnurl = isset($_POST['returnurl']) ? $_POST['returnurl'] : '?'; $returnurl .= '#' . smallHash($_POST['lf_linkdate']); // Scroll to the link which has been edited. $returnurl = generateLocation($returnurl, $_SERVER['HTTP_HOST'], array('addlink', 'post', 'edit_link')); header('Location: ' . $returnurl); // After canceling, redirect to the page the user was on. exit; } // -------- User clicked the "Delete" button when editing a link: Delete link from database. if (isset($_POST['delete_link'])) { if (!tokenOk($_POST['token'])) { die('Wrong token.'); } // We do not need to ask for confirmation: // - confirmation is handled by JavaScript // - we are protected from XSRF by the token. $linkdate = $_POST['lf_linkdate']; $pluginManager->executeHooks('delete_link', $LINKSDB[$linkdate]); unset($LINKSDB[$linkdate]); $LINKSDB->savedb($GLOBALS['config']['PAGECACHE']); // save to disk // If we are called from the bookmarklet, we must close the popup: if (isset($_GET['source']) && ($_GET['source'] == 'bookmarklet' || $_GET['source'] == 'firefoxsocialapi')) { echo '<script>self.close();</script>'; exit; } // Pick where we're going to redirect // ============================================================= // Basically, we can't redirect to where we were previously if it was a permalink // or an edit_link, because it would 404. // Cases: // - / : nothing in $_GET, redirect to self // - /?page : redirect to self // - /?searchterm : redirect to self (there might be other links) // - /?searchtags : redirect to self // - /permalink : redirect to / (the link does not exist anymore) // - /?edit_link : redirect to / (the link does not exist anymore) // PHP treats the permalink as a $_GET variable, so we need to check if every condition for self // redirect is not satisfied, and only then redirect to / $location = "?"; // Self redirection if (count($_GET) == 0 || isset($_GET['page']) || isset($_GET['searchterm']) || isset($_GET['searchtags'])) { if (isset($_POST['returnurl'])) { $location = $_POST['returnurl']; // Handle redirects given by the form } else { $location = generateLocation($_SERVER['HTTP_REFERER'], $_SERVER['HTTP_HOST'], array('delete_link')); } } header('Location: ' . $location); // After deleting the link, redirect to appropriate location exit; } // -------- User clicked the "EDIT" button on a link: Display link edit form. if (isset($_GET['edit_link'])) { $link = $LINKSDB[$_GET['edit_link']]; // Read database if (!$link) { header('Location: ?'); exit; } // Link not found in database. $data = array('linkcount' => count($LINKSDB), 'link' => $link, 'link_is_new' => false, 'token' => getToken(), 'http_referer' => isset($_SERVER['HTTP_REFERER']) ? escape($_SERVER['HTTP_REFERER']) : '', 'tags' => $LINKSDB->allTags()); $pluginManager->executeHooks('render_editlink', $data); foreach ($data as $key => $value) { $PAGE->assign($key, $value); } $PAGE->renderPage('editlink'); exit; } // -------- User want to post a new link: Display link edit form. if (isset($_GET['post'])) { $url = cleanup_url(escape($_GET['post'])); $link_is_new = false; // Check if URL is not already in database (in this case, we will edit the existing link) $link = $LINKSDB->getLinkFromUrl($url); if (!$link) { $link_is_new = true; $linkdate = strval(date('Ymd_His')); // Get title if it was provided in URL (by the bookmarklet). $title = empty($_GET['title']) ? '' : escape($_GET['title']); // Get description if it was provided in URL (by the bookmarklet). [Bronco added that] $description = empty($_GET['description']) ? '' : escape($_GET['description']); $tags = empty($_GET['tags']) ? '' : escape($_GET['tags']); $private = !empty($_GET['private']) && $_GET['private'] === "1" ? 1 : 0; // If this is an HTTP(S) link, we try go get the page to extract the title (otherwise we will to straight to the edit form.) if (empty($title) && strpos(get_url_scheme($url), 'http') !== false) { // Short timeout to keep the application responsive list($headers, $content) = get_http_response($url, 4); if (strpos($headers[0], '200 OK') !== false) { // Retrieve charset. $charset = get_charset($headers, $content); // Extract title. $title = html_extract_title($content); // Re-encode title in utf-8 if necessary. if (!empty($title) && $charset != 'utf-8') { $title = mb_convert_encoding($title, $charset, 'utf-8'); } } } if ($url == '') { $url = '?' . smallHash($linkdate); $title = 'Note: '; } $link = array('linkdate' => $linkdate, 'title' => $title, 'url' => $url, 'description' => $description, 'tags' => $tags, 'private' => $private); } $data = array('linkcount' => count($LINKSDB), 'link' => $link, 'link_is_new' => $link_is_new, 'token' => getToken(), 'http_referer' => isset($_SERVER['HTTP_REFERER']) ? escape($_SERVER['HTTP_REFERER']) : '', 'source' => isset($_GET['source']) ? $_GET['source'] : '', 'tags' => $LINKSDB->allTags()); $pluginManager->executeHooks('render_editlink', $data); foreach ($data as $key => $value) { $PAGE->assign($key, $value); } $PAGE->renderPage('editlink'); exit; } // -------- Export as Netscape Bookmarks HTML file. if ($targetPage == Router::$PAGE_EXPORT) { if (empty($_GET['what'])) { $PAGE->assign('linkcount', count($LINKSDB)); $PAGE->renderPage('export'); exit; } $exportWhat = $_GET['what']; if (!array_intersect(array('all', 'public', 'private'), array($exportWhat))) { die('What are you trying to export???'); } header('Content-Type: text/html; charset=utf-8'); header('Content-disposition: attachment; filename=bookmarks_' . $exportWhat . '_' . strval(date('Ymd_His')) . '.html'); $currentdate = date('Y/m/d H:i:s'); echo <<<HTML <!DOCTYPE NETSCAPE-Bookmark-file-1> <!-- This is an automatically generated file. It will be read and overwritten. DO NOT EDIT! --> <!-- Shaarli {$exportWhat} bookmarks export on {$currentdate} --> <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8"> <TITLE>Bookmarks</TITLE> <H1>Bookmarks</H1> HTML; foreach ($LINKSDB as $link) { if ($exportWhat == 'all' || $exportWhat == 'private' && $link['private'] != 0 || $exportWhat == 'public' && $link['private'] == 0) { echo '<DT><A HREF="' . $link['url'] . '" ADD_DATE="' . linkdate2timestamp($link['linkdate']) . '" PRIVATE="' . $link['private'] . '"'; if ($link['tags'] != '') { echo ' TAGS="' . str_replace(' ', ',', $link['tags']) . '"'; } echo '>' . $link['title'] . "</A>\n"; if ($link['description'] != '') { echo '<DD>' . $link['description'] . "\n"; } } } exit; } // -------- User is uploading a file for import if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"], 'do=upload')) { // If file is too big, some form field may be missing. if (!isset($_POST['token']) || !isset($_FILES) || isset($_FILES['filetoupload']['size']) && $_FILES['filetoupload']['size'] == 0) { $returnurl = empty($_SERVER['HTTP_REFERER']) ? '?' : $_SERVER['HTTP_REFERER']; echo '<script>alert("The file you are trying to upload is probably bigger than what this webserver can accept (' . getMaxFileSize() . ' bytes). Please upload in smaller chunks.");document.location=\'' . escape($returnurl) . '\';</script>'; exit; } if (!tokenOk($_POST['token'])) { die('Wrong token.'); } importFile(); exit; } // -------- Show upload/import dialog: if ($targetPage == Router::$PAGE_IMPORT) { $PAGE->assign('linkcount', count($LINKSDB)); $PAGE->assign('token', getToken()); $PAGE->assign('maxfilesize', getMaxFileSize()); $PAGE->renderPage('import'); exit; } // -------- Otherwise, simply display search form and links: showLinkList($PAGE, $LINKSDB); exit; }
} } if (!importFile($path, $meta)) { pieError("ImportError", array('file' => htmlspecialchars($file))); } $count++; $size += filesize($path); } } } else { // Retrieve the list of files of the FILE path. if (!($list = getFileList($_REQUEST['filepath']))) { pieError("ImportError"); } // Validate if the files already exist. $num = checkFiles($list); $count = 0; $size = 0; // Import the files of the list. foreach ($list as $file) { $path = $_REQUEST['filepath'] . "/{$file}"; if (!importFile($path, array())) { pieError("ImportError", array('file' => htmlspecialchars($file))); } $count++; $size += filesize($path); } } pieLog("alter"); pieNotice("ImportSuccess", array('num' => $num, 'count' => $count, 'size' => pieMakeSize($size))); pieTail();