X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=index.php;h=baae41793ed579f95b4b1a19b163d1e9fd7ecc04;hb=340777ad3f0b4e798a3eedfb730d993972adbe3e;hp=74091f37703a63d90c2102da7804b6ab4e524763;hpb=f66a1990e5d93a6f302ce594968e5e717b93da72;p=github%2Fshaarli%2FShaarli.git diff --git a/index.php b/index.php index 74091f37..baae4179 100644 --- a/index.php +++ b/index.php @@ -1,6 +1,6 @@ /shaarli/ define('WEB_PATH', substr($_SERVER["REQUEST_URI"], 0, 1+strrpos($_SERVER["REQUEST_URI"], '/', 0))); @@ -160,6 +161,8 @@ require_once 'application/HttpUtils.php'; require_once 'application/LinkDB.php'; require_once 'application/LinkFilter.php'; require_once 'application/LinkUtils.php'; +require_once 'application/NetscapeBookmarkUtils.php'; +require_once 'application/PageBuilder.php'; require_once 'application/TimeZone.php'; require_once 'application/Url.php'; require_once 'application/Utils.php'; @@ -493,9 +496,9 @@ if (isset($_POST['login'])) else { ban_loginFailed(); - $redir = ''; + $redir = '&username='. $_POST['login']; if (isset($_GET['post'])) { - $redir = '?post=' . urlencode($_GET['post']); + $redir .= '&post=' . urlencode($_GET['post']); foreach (array('description', 'source', 'title') as $param) { if (!empty($_GET[$param])) { $redir .= '&' . $param . '=' . urlencode($_GET[$param]); @@ -560,135 +563,13 @@ function tokenOk($token) return false; // Wrong token, or already used. } -// ------------------------------------------------------------------------------------------ -/* This class is in charge of building the final page. - (This is basically a wrapper around RainTPL which pre-fills some fields.) - p = new pageBuilder; - p.assign('myfield','myvalue'); - p.renderPage('mytemplate'); - -*/ -class pageBuilder -{ - private $tpl; // RainTPL template - - function __construct() - { - $this->tpl = false; - } - - /** - * Initialize all default tpl tags. - */ - private function initialize() - { - $this->tpl = new RainTPL; - - try { - $version = ApplicationUtils::checkUpdate( - shaarli_version, - $GLOBALS['config']['UPDATECHECK_FILENAME'], - $GLOBALS['config']['UPDATECHECK_INTERVAL'], - $GLOBALS['config']['ENABLE_UPDATECHECK'], - isLoggedIn(), - $GLOBALS['config']['UPDATECHECK_BRANCH'] - ); - $this->tpl->assign('newVersion', escape($version)); - $this->tpl->assign('versionError', ''); - - } catch (Exception $exc) { - logm($GLOBALS['config']['LOG_FILE'], $_SERVER['REMOTE_ADDR'], $exc->getMessage()); - $this->tpl->assign('newVersion', ''); - $this->tpl->assign('versionError', escape($exc->getMessage())); - } - - $this->tpl->assign('feedurl', escape(index_url($_SERVER))); - $searchcrits = ''; // Search criteria - if (!empty($_GET['searchtags'])) { - $searchcrits .= '&searchtags=' . urlencode($_GET['searchtags']); - } - if (!empty($_GET['searchterm'])) { - $searchcrits .= '&searchterm=' . urlencode($_GET['searchterm']); - } - $this->tpl->assign('searchcrits', $searchcrits); - $this->tpl->assign('source', index_url($_SERVER)); - $this->tpl->assign('version', shaarli_version); - $this->tpl->assign('scripturl', index_url($_SERVER)); - $this->tpl->assign('pagetitle', 'Shaarli'); - $this->tpl->assign('privateonly', !empty($_SESSION['privateonly'])); // Show only private links? - if (!empty($GLOBALS['title'])) { - $this->tpl->assign('pagetitle', $GLOBALS['title']); - } - if (!empty($GLOBALS['titleLink'])) { - $this->tpl->assign('titleLink', $GLOBALS['titleLink']); - } - if (!empty($GLOBALS['pagetitle'])) { - $this->tpl->assign('pagetitle', $GLOBALS['pagetitle']); - } - $this->tpl->assign('shaarlititle', empty($GLOBALS['title']) ? 'Shaarli': $GLOBALS['title']); - if (!empty($GLOBALS['plugin_errors'])) { - $this->tpl->assign('plugin_errors', $GLOBALS['plugin_errors']); - } - } - - // The following assign() method is basically the same as RainTPL (except that it's lazy) - public function assign($what,$where) - { - if ($this->tpl===false) $this->initialize(); // Lazy initialization - $this->tpl->assign($what,$where); - } - - /** - * Assign an array of data to the template builder. - * - * @param array $data Data to assign. - * - * @return false if invalid data. - */ - public function assignAll($data) - { - // Lazy initialization - if ($this->tpl === false) { - $this->initialize(); - } - - if (empty($data) || !is_array($data)){ - return false; - } - - foreach ($data as $key => $value) { - $this->assign($key, $value); - } - } - - // Render a specific page (using a template). - // e.g. pb.renderPage('picwall') - public function renderPage($page) - { - if ($this->tpl===false) $this->initialize(); // Lazy initialization - $this->tpl->draw($page); - } - - /** - * Render a 404 page (uses the template : tpl/404.tpl) - * - * usage : $PAGE->render404('The link was deleted') - * @param string $message A messate to display what is not found - */ - public function render404($message='The page you are trying to reach does not exist or has been deleted.') { - header($_SERVER['SERVER_PROTOCOL'] . ' 404 Not Found'); - $this->tpl->assign('error_message', $message); - $this->renderPage('404'); - } -} - // ------------------------------------------------------------------------------------------ // Daily RSS feed: 1 RSS entry per day giving all the links on that day. // Gives the last 7 days (which have links). // This RSS feed cannot be filtered. function showDailyRSS() { // Cache system - $query = $_SERVER["QUERY_STRING"]; + $query = $_SERVER['QUERY_STRING']; $cache = new CachedPage( $GLOBALS['config']['PAGECACHE'], page_url($_SERVER), @@ -706,7 +587,8 @@ function showDailyRSS() { $GLOBALS['config']['DATASTORE'], isLoggedIn(), $GLOBALS['config']['HIDE_PUBLIC_LINKS'], - $GLOBALS['redirector'] + $GLOBALS['redirector'], + $GLOBALS['config']['REDIRECTOR_URLENCODE'] ); /* Some Shaarlies may have very few links, so we need to look @@ -791,16 +673,10 @@ function showDailyRSS() { * Show the 'Daily' page. * * @param PageBuilder $pageBuilder Template engine wrapper. + * @param LinkDB $LINKSDB LinkDB instance. */ -function showDaily($pageBuilder) +function showDaily($pageBuilder, $LINKSDB) { - $LINKSDB = new LinkDB( - $GLOBALS['config']['DATASTORE'], - isLoggedIn(), - $GLOBALS['config']['HIDE_PUBLIC_LINKS'], - $GLOBALS['redirector'] - ); - $day=Date('Ymd',strtotime('-1 day')); // Yesterday, in format YYYYMMDD. if (isset($_GET['day'])) $day=$_GET['day']; @@ -860,7 +736,6 @@ function showDaily($pageBuilder) $dayDate = DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $day.'_000000'); $data = array( 'linksToDisplay' => $linksToDisplay, - 'linkcount' => count($LINKSDB), 'cols' => $columns, 'day' => $dayDate->getTimestamp(), 'previousday' => $previousday, @@ -892,7 +767,8 @@ function renderPage() $GLOBALS['config']['DATASTORE'], isLoggedIn(), $GLOBALS['config']['HIDE_PUBLIC_LINKS'], - $GLOBALS['redirector'] + $GLOBALS['redirector'], + $GLOBALS['config']['REDIRECTOR_URLENCODE'] ); $updater = new Updater( @@ -914,7 +790,9 @@ function renderPage() die($e->getMessage()); } - $PAGE = new pageBuilder; + $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'] : ''; @@ -945,12 +823,15 @@ function renderPage() 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')) + if (isset($_SERVER['QUERY_STRING']) && startsWith($_SERVER['QUERY_STRING'], 'do=logout')) { invalidateCaches($GLOBALS['config']['PAGECACHE']); logout(); @@ -978,7 +859,6 @@ function renderPage() } $data = array( - 'linkcount' => count($LINKSDB), 'linksToDisplay' => $linksToDisplay, ); $pluginManager->executeHooks('render_picwall', $data, array('loggedin' => isLoggedIn())); @@ -1015,15 +895,19 @@ function renderPage() 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. - { - $tagList[$key] = array('count'=>$value,'size'=>log($value, 15) / log($maxcount, 30) * (22-6) + 6); + $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( - 'linkcount' => count($LINKSDB), 'tags' => $tagList, ); $pluginManager->executeHooks('render_tagcloud', $data, array('loggedin' => isLoggedIn())); @@ -1038,7 +922,7 @@ function renderPage() // Daily page. if ($targetPage == Router::$PAGE_DAILY) { - showDaily($PAGE); + showDaily($PAGE, $LINKSDB); } // ATOM and RSS feed. @@ -1054,7 +938,7 @@ function renderPage() startsWith($query,'do='. $targetPage) && !isLoggedIn() ); $cached = $cache->cachedVersion(); - if (false && !empty($cached)) { + if (!empty($cached)) { echo $cached; exit; } @@ -1196,12 +1080,6 @@ function renderPage() 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'])); @@ -1217,7 +1095,6 @@ function renderPage() if ($targetPage == Router::$PAGE_TOOLS) { $data = array( - 'linkcount' => count($LINKSDB), 'pageabsaddr' => index_url($_SERVER), ); $pluginManager->executeHooks('render_tools', $data); @@ -1262,7 +1139,6 @@ function renderPage() } else // show the change password form. { - $PAGE->assign('linkcount',count($LINKSDB)); $PAGE->assign('token',getToken()); $PAGE->renderPage('changepassword'); exit; @@ -1274,11 +1150,15 @@ function renderPage() { if (!empty($_POST['title']) ) { - if (!tokenOk($_POST['token'])) die('Wrong token.'); // Go away! + 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']; + 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']; @@ -1306,7 +1186,6 @@ function renderPage() } else // Show the configuration form. { - $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'] ); @@ -1322,7 +1201,6 @@ function renderPage() 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'); @@ -1371,7 +1249,6 @@ function renderPage() // -------- 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; } @@ -1497,7 +1374,6 @@ function renderPage() $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(), @@ -1516,7 +1392,7 @@ function renderPage() // -------- User want to post a new link: Display link edit form. if (isset($_GET['post'])) { - $url = cleanup_url(escape($_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) @@ -1541,8 +1417,8 @@ function renderPage() // 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 (! empty($title) && strtolower($charset) != 'utf-8') { + $title = mb_convert_encoding($title, 'utf-8', $charset); } } } @@ -1551,6 +1427,8 @@ function renderPage() $url = '?' . smallHash($linkdate); $title = 'Note: '; } + $url = escape($url); + $title = escape($title); $link = array( 'linkdate' => $linkdate, @@ -1563,7 +1441,6 @@ function renderPage() } $data = array( - 'linkcount' => count($LINKSDB), 'link' => $link, 'link_is_new' => $link_is_new, 'token' => getToken(), // XSRF protection. @@ -1581,49 +1458,52 @@ function renderPage() exit; } - // -------- Export as Netscape Bookmarks HTML file. - if ($targetPage == Router::$PAGE_EXPORT) - { - if (empty($_GET['what'])) - { - $PAGE->assign('linkcount',count($LINKSDB)); + if ($targetPage == Router::$PAGE_EXPORT) { + // Export links as a Netscape Bookmarks file + + if (empty($_GET['selection'])) { $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 << - - - -Bookmarks -

Bookmarks

-HTML; - foreach($LINKSDB as $link) - { - if ($exportWhat=='all' || - ($exportWhat=='private' && $link['private']!=0) || - ($exportWhat=='public' && $link['private']==0)) - { - $date = DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, $link['linkdate']); - echo '
'.$link['title']."\n"; - if ($link['description']!='') echo '
'.$link['description']."\n"; - } + // 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; } - exit; + + 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 (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)) @@ -1633,14 +1513,13 @@ HTML; exit; } if (!tokenOk($_POST['token'])) die('Wrong token.'); - importFile(); + importFile($LINKSDB); 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'); @@ -1702,15 +1581,10 @@ HTML; // ----------------------------------------------------------------------------------------------- // Process the import file form. -function importFile() +function importFile($LINKSDB) { if (!isLoggedIn()) { die('Not allowed.'); } - $LINKSDB = new LinkDB( - $GLOBALS['config']['DATASTORE'], - isLoggedIn(), - $GLOBALS['config']['HIDE_PUBLIC_LINKS'], - $GLOBALS['redirector'] - ); + $filename=$_FILES['filetoupload']['name']; $filesize=$_FILES['filetoupload']['size']; $data=file_get_contents($_FILES['filetoupload']['tmp_name']); @@ -1731,7 +1605,7 @@ function importFile() { $link = array('linkdate'=>'','title'=>'','url'=>'','description'=>'','tags'=>'','private'=>0); $d = explode('
',$html); - if (startswith($d[0],'(.*?)!i',$d[0],$matches); $link['title'] = (isset($matches[1]) ? trim($matches[1]) : ''); // Get title @@ -1877,7 +1751,6 @@ function buildLinkList($PAGE,$LINKSDB) // Fill all template fields. $data = array( - 'linkcount' => count($LINKSDB), 'previous_page_url' => $previous_page_url, 'next_page_url' => $next_page_url, 'page_current' => $page, @@ -2116,10 +1989,10 @@ function install() if (!empty($_POST['setlogin']) && !empty($_POST['setpassword'])) { $tz = 'UTC'; - if (!empty($_POST['continent']) && !empty($_POST['city'])) { - if (isTimeZoneValid($_POST['continent'], $_POST['city'])) { - $tz = $_POST['continent'].'/'.$_POST['city']; - } + if (!empty($_POST['continent']) && !empty($_POST['city']) + && isTimeZoneValid($_POST['continent'], $_POST['city']) + ) { + $tz = $_POST['continent'].'/'.$_POST['city']; } $GLOBALS['timezone'] = $tz; // Everything is ok, let's create config file. @@ -2152,7 +2025,7 @@ function install() $timezone_html = 'Timezone:'.$timezone_form.''; } - $PAGE = new pageBuilder; + $PAGE = new PageBuilder(); $PAGE->assign('timezone_html',$timezone_html); $PAGE->assign('timezone_js',$timezone_js); $PAGE->renderPage('install'); @@ -2202,7 +2075,7 @@ function genThumbnail() // Is this a link to an image, or to a flickr page ? $imageurl=''; - if (endswith(parse_url($url,PHP_URL_PATH),'.jpg')) + if (endsWith(parse_url($url, PHP_URL_PATH), '.jpg')) { // This is a direct link to an image. e.g. http://farm1.staticflickr.com/5/5921913_ac83ed27bd_o.jpg preg_match('!(http://farm\d+\.staticflickr\.com/\d+/\d+_\w+_)\w.jpg!',$url,$matches); if (!empty($matches[1])) $imageurl=$matches[1].'m.jpg'; @@ -2379,8 +2252,8 @@ function resizeImage($filepath) return true; } -if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=genthumbnail')) { genThumbnail(); exit; } // Thumbnail generation/cache does not need the link database. -if (isset($_SERVER["QUERY_STRING"]) && startswith($_SERVER["QUERY_STRING"],'do=dailyrss')) { showDailyRSS(); exit; } +if (isset($_SERVER['QUERY_STRING']) && startsWith($_SERVER['QUERY_STRING'], 'do=genthumbnail')) { genThumbnail(); exit; } // Thumbnail generation/cache does not need the link database. +if (isset($_SERVER['QUERY_STRING']) && startsWith($_SERVER['QUERY_STRING'], 'do=dailyrss')) { showDailyRSS(); exit; } if (!isset($_SESSION['LINKS_PER_PAGE'])) $_SESSION['LINKS_PER_PAGE']=$GLOBALS['config']['LINKS_PER_PAGE']; renderPage(); ?>