aboutsummaryrefslogtreecommitdiffhomepage
path: root/index.php
diff options
context:
space:
mode:
Diffstat (limited to 'index.php')
-rw-r--r--index.php165
1 files changed, 46 insertions, 119 deletions
diff --git a/index.php b/index.php
index ab51fa23..9f50d153 100644
--- a/index.php
+++ b/index.php
@@ -1,6 +1,6 @@
1<?php 1<?php
2/** 2/**
3 * Shaarli v0.7.0 - Shaare your links... 3 * Shaarli v0.8.0 - Shaare your links...
4 * 4 *
5 * The personal, minimalist, super-fast, database free, bookmarking service. 5 * The personal, minimalist, super-fast, database free, bookmarking service.
6 * 6 *
@@ -25,7 +25,7 @@ if (date_default_timezone_get() == '') {
25/* 25/*
26 * PHP configuration 26 * PHP configuration
27 */ 27 */
28define('shaarli_version', '0.7.0'); 28define('shaarli_version', '0.8.0');
29 29
30// http://server.com/x/shaarli --> /shaarli/ 30// http://server.com/x/shaarli --> /shaarli/
31define('WEB_PATH', substr($_SERVER['REQUEST_URI'], 0, 1+strrpos($_SERVER['REQUEST_URI'], '/', 0))); 31define('WEB_PATH', substr($_SERVER['REQUEST_URI'], 0, 1+strrpos($_SERVER['REQUEST_URI'], '/', 0)));
@@ -44,6 +44,20 @@ error_reporting(E_ALL^E_WARNING);
44//error_reporting(-1); 44//error_reporting(-1);
45 45
46 46
47// 3rd-party libraries
48if (! file_exists(__DIR__ . '/vendor/autoload.php')) {
49 header('Content-Type: text/plain; charset=utf-8');
50 echo "Error: missing Composer configuration\n\n"
51 ."If you installed Shaarli through Git or using the development branch,\n"
52 ."please refer to the installation documentation to install PHP"
53 ." dependencies using Composer:\n"
54 ."- https://github.com/shaarli/Shaarli/wiki/Server-requirements\n"
55 ."- https://github.com/shaarli/Shaarli/wiki/Download-and-Installation";
56 exit;
57}
58require_once 'inc/rain.tpl.class.php';
59require_once __DIR__ . '/vendor/autoload.php';
60
47// Shaarli library 61// Shaarli library
48require_once 'application/ApplicationUtils.php'; 62require_once 'application/ApplicationUtils.php';
49require_once 'application/Cache.php'; 63require_once 'application/Cache.php';
@@ -53,6 +67,7 @@ require_once 'application/config/ConfigPlugin.php';
53require_once 'application/FeedBuilder.php'; 67require_once 'application/FeedBuilder.php';
54require_once 'application/FileUtils.php'; 68require_once 'application/FileUtils.php';
55require_once 'application/HttpUtils.php'; 69require_once 'application/HttpUtils.php';
70require_once 'application/Languages.php';
56require_once 'application/LinkDB.php'; 71require_once 'application/LinkDB.php';
57require_once 'application/LinkFilter.php'; 72require_once 'application/LinkFilter.php';
58require_once 'application/LinkUtils.php'; 73require_once 'application/LinkUtils.php';
@@ -64,7 +79,6 @@ require_once 'application/Utils.php';
64require_once 'application/PluginManager.php'; 79require_once 'application/PluginManager.php';
65require_once 'application/Router.php'; 80require_once 'application/Router.php';
66require_once 'application/Updater.php'; 81require_once 'application/Updater.php';
67require_once 'inc/rain.tpl.class.php';
68 82
69// Ensure the PHP version is supported 83// Ensure the PHP version is supported
70try { 84try {
@@ -792,8 +806,6 @@ function renderPage($conf, $pluginManager)
792 if ($targetPage == Router::$PAGE_LOGIN) 806 if ($targetPage == Router::$PAGE_LOGIN)
793 { 807 {
794 if ($conf->get('security.open_shaarli')) { header('Location: ?'); exit; } // No need to login for open Shaarli 808 if ($conf->get('security.open_shaarli')) { header('Location: ?'); exit; } // No need to login for open Shaarli
795 $token=''; if (ban_canLogin($conf)) $token=getToken($conf); // Do not waste token generation if not useful.
796 $PAGE->assign('token',$token);
797 if (isset($_GET['username'])) { 809 if (isset($_GET['username'])) {
798 $PAGE->assign('username', escape($_GET['username'])); 810 $PAGE->assign('username', escape($_GET['username']));
799 } 811 }
@@ -1114,7 +1126,6 @@ function renderPage($conf, $pluginManager)
1114 } 1126 }
1115 else // show the change password form. 1127 else // show the change password form.
1116 { 1128 {
1117 $PAGE->assign('token',getToken($conf));
1118 $PAGE->renderPage('changepassword'); 1129 $PAGE->renderPage('changepassword');
1119 exit; 1130 exit;
1120 } 1131 }
@@ -1161,7 +1172,6 @@ function renderPage($conf, $pluginManager)
1161 } 1172 }
1162 else // Show the configuration form. 1173 else // Show the configuration form.
1163 { 1174 {
1164 $PAGE->assign('token',getToken($conf));
1165 $PAGE->assign('title', $conf->get('general.title')); 1175 $PAGE->assign('title', $conf->get('general.title'));
1166 $PAGE->assign('redirector', $conf->get('redirector.url')); 1176 $PAGE->assign('redirector', $conf->get('redirector.url'));
1167 list($timezone_form, $timezone_js) = generateTimeZoneForm($conf->get('general.timezone')); 1177 list($timezone_form, $timezone_js) = generateTimeZoneForm($conf->get('general.timezone'));
@@ -1181,7 +1191,6 @@ function renderPage($conf, $pluginManager)
1181 if ($targetPage == Router::$PAGE_CHANGETAG) 1191 if ($targetPage == Router::$PAGE_CHANGETAG)
1182 { 1192 {
1183 if (empty($_POST['fromtag']) || (empty($_POST['totag']) && isset($_POST['renametag']))) { 1193 if (empty($_POST['fromtag']) || (empty($_POST['totag']) && isset($_POST['renametag']))) {
1184 $PAGE->assign('token', getToken($conf));
1185 $PAGE->assign('tags', $LINKSDB->allTags()); 1194 $PAGE->assign('tags', $LINKSDB->allTags());
1186 $PAGE->renderPage('changetag'); 1195 $PAGE->renderPage('changetag');
1187 exit; 1196 exit;
@@ -1356,7 +1365,6 @@ function renderPage($conf, $pluginManager)
1356 $data = array( 1365 $data = array(
1357 'link' => $link, 1366 'link' => $link,
1358 'link_is_new' => false, 1367 'link_is_new' => false,
1359 'token' => getToken($conf),
1360 'http_referer' => (isset($_SERVER['HTTP_REFERER']) ? escape($_SERVER['HTTP_REFERER']) : ''), 1368 'http_referer' => (isset($_SERVER['HTTP_REFERER']) ? escape($_SERVER['HTTP_REFERER']) : ''),
1361 'tags' => $LINKSDB->allTags(), 1369 'tags' => $LINKSDB->allTags(),
1362 ); 1370 );
@@ -1423,11 +1431,10 @@ function renderPage($conf, $pluginManager)
1423 $data = array( 1431 $data = array(
1424 'link' => $link, 1432 'link' => $link,
1425 'link_is_new' => $link_is_new, 1433 'link_is_new' => $link_is_new,
1426 'token' => getToken($conf), // XSRF protection.
1427 'http_referer' => (isset($_SERVER['HTTP_REFERER']) ? escape($_SERVER['HTTP_REFERER']) : ''), 1434 'http_referer' => (isset($_SERVER['HTTP_REFERER']) ? escape($_SERVER['HTTP_REFERER']) : ''),
1428 'source' => (isset($_GET['source']) ? $_GET['source'] : ''), 1435 'source' => (isset($_GET['source']) ? $_GET['source'] : ''),
1429 'tags' => $LINKSDB->allTags(), 1436 'tags' => $LINKSDB->allTags(),
1430 'default_private_links' => $conf->get('default_private_links', false), 1437 'default_private_links' => $conf->get('privacy.default_private_links', false),
1431 ); 1438 );
1432 $pluginManager->executeHooks('render_editlink', $data); 1439 $pluginManager->executeHooks('render_editlink', $data);
1433 1440
@@ -1483,27 +1490,37 @@ function renderPage($conf, $pluginManager)
1483 exit; 1490 exit;
1484 } 1491 }
1485 1492
1486 // -------- User is uploading a file for import 1493 if ($targetPage == Router::$PAGE_IMPORT) {
1487 if (isset($_SERVER['QUERY_STRING']) && startsWith($_SERVER['QUERY_STRING'], 'do=upload')) 1494 // Upload a Netscape bookmark dump to import its contents
1488 { 1495
1489 // If file is too big, some form field may be missing. 1496 if (! isset($_POST['token']) || ! isset($_FILES['filetoupload'])) {
1490 if (!isset($_POST['token']) || (!isset($_FILES)) || (isset($_FILES['filetoupload']['size']) && $_FILES['filetoupload']['size']==0)) 1497 // Show import dialog
1491 { 1498 $PAGE->assign('maxfilesize', getMaxFileSize());
1492 $returnurl = ( empty($_SERVER['HTTP_REFERER']) ? '?' : $_SERVER['HTTP_REFERER'] ); 1499 $PAGE->renderPage('import');
1493 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>';
1494 exit; 1500 exit;
1495 } 1501 }
1496 if (!tokenOk($_POST['token'])) die('Wrong token.');
1497 importFile($LINKSDB);
1498 exit;
1499 }
1500 1502
1501 // -------- Show upload/import dialog: 1503 // Import bookmarks from an uploaded file
1502 if ($targetPage == Router::$PAGE_IMPORT) 1504 if (isset($_FILES['filetoupload']['size']) && $_FILES['filetoupload']['size'] == 0) {
1503 { 1505 // The file is too big or some form field may be missing.
1504 $PAGE->assign('token',getToken($conf)); 1506 echo '<script>alert("The file you are trying to upload is probably'
1505 $PAGE->assign('maxfilesize',getMaxFileSize()); 1507 .' bigger than what this webserver can accept ('
1506 $PAGE->renderPage('import'); 1508 .getMaxFileSize().' bytes).'
1509 .' Please upload in smaller chunks.");document.location=\'?do='
1510 .Router::$PAGE_IMPORT .'\';</script>';
1511 exit;
1512 }
1513 if (! tokenOk($_POST['token'])) {
1514 die('Wrong token.');
1515 }
1516 $status = NetscapeBookmarkUtils::import(
1517 $_POST,
1518 $_FILES,
1519 $LINKSDB,
1520 $conf->get('resource.page_cache')
1521 );
1522 echo '<script>alert("'.$status.'");document.location=\'?do='
1523 .Router::$PAGE_IMPORT .'\';</script>';
1507 exit; 1524 exit;
1508 } 1525 }
1509 1526
@@ -1561,95 +1578,6 @@ function renderPage($conf, $pluginManager)
1561} 1578}
1562 1579
1563/** 1580/**
1564 * Process the import file form.
1565 *
1566 * @param LinkDB $LINKSDB Loaded LinkDB instance.
1567 * @param ConfigManager $conf Configuration Manager instance.
1568 */
1569function importFile($LINKSDB, $conf)
1570{
1571 if (!isLoggedIn()) { die('Not allowed.'); }
1572
1573 $filename=$_FILES['filetoupload']['name'];
1574 $filesize=$_FILES['filetoupload']['size'];
1575 $data=file_get_contents($_FILES['filetoupload']['tmp_name']);
1576 $private = (empty($_POST['private']) ? 0 : 1); // Should the links be imported as private?
1577 $overwrite = !empty($_POST['overwrite']) ; // Should the imported links overwrite existing ones?
1578 $import_count=0;
1579
1580 // Sniff file type:
1581 $type='unknown';
1582 if (startsWith($data,'<!DOCTYPE NETSCAPE-Bookmark-file-1>')) $type='netscape'; // Netscape bookmark file (aka Firefox).
1583
1584 // Then import the bookmarks.
1585 if ($type=='netscape')
1586 {
1587 // This is a standard Netscape-style bookmark file.
1588 // This format is supported by all browsers (except IE, of course), also Delicious, Diigo and others.
1589 foreach(explode('<DT>',$data) as $html) // explode is very fast
1590 {
1591 $link = array('linkdate'=>'','title'=>'','url'=>'','description'=>'','tags'=>'','private'=>0);
1592 $d = explode('<DD>',$html);
1593 if (startsWith($d[0], '<A '))
1594 {
1595 $link['description'] = (isset($d[1]) ? html_entity_decode(trim($d[1]),ENT_QUOTES,'UTF-8') : ''); // Get description (optional)
1596 preg_match('!<A .*?>(.*?)</A>!i',$d[0],$matches); $link['title'] = (isset($matches[1]) ? trim($matches[1]) : ''); // Get title
1597 $link['title'] = html_entity_decode($link['title'],ENT_QUOTES,'UTF-8');
1598 preg_match_all('! ([A-Z_]+)=\"(.*?)"!i',$html,$matches,PREG_SET_ORDER); // Get all other attributes
1599 $raw_add_date=0;
1600 foreach($matches as $m)
1601 {
1602 $attr=$m[1]; $value=$m[2];
1603 if ($attr=='HREF') $link['url']=html_entity_decode($value,ENT_QUOTES,'UTF-8');
1604 elseif ($attr=='ADD_DATE')
1605 {
1606 $raw_add_date=intval($value);
1607 if ($raw_add_date>30000000000) $raw_add_date/=1000; //If larger than year 2920, then was likely stored in milliseconds instead of seconds
1608 }
1609 elseif ($attr=='PRIVATE') $link['private']=($value=='0'?0:1);
1610 elseif ($attr=='TAGS') $link['tags']=html_entity_decode(str_replace(',',' ',$value),ENT_QUOTES,'UTF-8');
1611 }
1612 if ($link['url']!='')
1613 {
1614 if ($private==1) $link['private']=1;
1615 $dblink = $LINKSDB->getLinkFromUrl($link['url']); // See if the link is already in database.
1616 if ($dblink==false)
1617 { // Link not in database, let's import it...
1618 if (empty($raw_add_date)) $raw_add_date=time(); // In case of shitty bookmark file with no ADD_DATE
1619
1620 // Make sure date/time is not already used by another link.
1621 // (Some bookmark files have several different links with the same ADD_DATE)
1622 // We increment date by 1 second until we find a date which is not used in DB.
1623 // (so that links that have the same date/time are more or less kept grouped by date, but do not conflict.)
1624 while (!empty($LINKSDB[date('Ymd_His',$raw_add_date)])) { $raw_add_date++; }// Yes, I know it's ugly.
1625 $link['linkdate']=date('Ymd_His',$raw_add_date);
1626 $LINKSDB[$link['linkdate']] = $link;
1627 $import_count++;
1628 }
1629 else // Link already present in database.
1630 {
1631 if ($overwrite)
1632 { // If overwrite is required, we import link data, except date/time.
1633 $link['linkdate']=$dblink['linkdate'];
1634 $LINKSDB[$link['linkdate']] = $link;
1635 $import_count++;
1636 }
1637 }
1638
1639 }
1640 }
1641 }
1642 $LINKSDB->savedb($conf->get('resource.page_cache'));
1643
1644 echo '<script>alert("File '.json_encode($filename).' ('.$filesize.' bytes) was successfully processed: '.$import_count.' links imported.");document.location=\'?\';</script>';
1645 }
1646 else
1647 {
1648 echo '<script>alert("File '.json_encode($filename).' ('.$filesize.' bytes) has an unknown file format. Nothing was imported.");document.location=\'?\';</script>';
1649 }
1650}
1651
1652/**
1653 * Template for the list of links (<div id="linklist">) 1581 * Template for the list of links (<div id="linklist">)
1654 * This function fills all the necessary fields in the $PAGE for the template 'linklist.html' 1582 * This function fills all the necessary fields in the $PAGE for the template 'linklist.html'
1655 * 1583 *
@@ -1743,7 +1671,6 @@ function buildLinkList($PAGE,$LINKSDB, $conf, $pluginManager)
1743 'search_term' => $searchterm, 1671 'search_term' => $searchterm,
1744 'search_tags' => $searchtags, 1672 'search_tags' => $searchtags,
1745 'redirector' => $conf->get('redirector.url'), // Optional redirector URL. 1673 'redirector' => $conf->get('redirector.url'), // Optional redirector URL.
1746 'token' => $token,
1747 'links' => $linkDisp, 1674 'links' => $linkDisp,
1748 'tags' => $LINKSDB->allTags(), 1675 'tags' => $LINKSDB->allTags(),
1749 ); 1676 );