Process bookmarks import through Slim controller
This commit is contained in:
parent
c70ff64a61
commit
78657347c5
12 changed files with 256 additions and 84 deletions
|
@ -33,6 +33,8 @@ public function index(Request $request, Response $response): Response
|
||||||
*/
|
*/
|
||||||
public function export(Request $request, Response $response): Response
|
public function export(Request $request, Response $response): Response
|
||||||
{
|
{
|
||||||
|
$this->checkToken($request);
|
||||||
|
|
||||||
$selection = $request->getParam('selection');
|
$selection = $request->getParam('selection');
|
||||||
|
|
||||||
if (empty($selection)) {
|
if (empty($selection)) {
|
||||||
|
@ -74,19 +76,4 @@ public function export(Request $request, Response $response): Response
|
||||||
|
|
||||||
return $response->write($this->render('export.bookmarks'));
|
return $response->write($this->render('export.bookmarks'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param mixed[] $data Variables passed to the template engine
|
|
||||||
*
|
|
||||||
* @return mixed[] Template data after active plugins render_picwall hook execution.
|
|
||||||
*/
|
|
||||||
protected function executeHooks(array $data): array
|
|
||||||
{
|
|
||||||
$this->container->pluginManager->executeHooks(
|
|
||||||
'render_tools',
|
|
||||||
$data
|
|
||||||
);
|
|
||||||
|
|
||||||
return $data;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
81
application/front/controller/admin/ImportController.php
Normal file
81
application/front/controller/admin/ImportController.php
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Shaarli\Front\Controller\Admin;
|
||||||
|
|
||||||
|
use Psr\Http\Message\UploadedFileInterface;
|
||||||
|
use Slim\Http\Request;
|
||||||
|
use Slim\Http\Response;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class ImportController
|
||||||
|
*
|
||||||
|
* Slim controller used to display Shaarli data import page,
|
||||||
|
* and import bookmarks from Netscape Bookmarks file.
|
||||||
|
*/
|
||||||
|
class ImportController extends ShaarliAdminController
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* GET /admin/import - Display import page
|
||||||
|
*/
|
||||||
|
public function index(Request $request, Response $response): Response
|
||||||
|
{
|
||||||
|
$this->assignView(
|
||||||
|
'maxfilesize',
|
||||||
|
get_max_upload_size(
|
||||||
|
ini_get('post_max_size'),
|
||||||
|
ini_get('upload_max_filesize'),
|
||||||
|
false
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$this->assignView(
|
||||||
|
'maxfilesizeHuman',
|
||||||
|
get_max_upload_size(
|
||||||
|
ini_get('post_max_size'),
|
||||||
|
ini_get('upload_max_filesize'),
|
||||||
|
true
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$this->assignView('pagetitle', t('Import') .' - '. $this->container->conf->get('general.title', 'Shaarli'));
|
||||||
|
|
||||||
|
return $response->write($this->render('import'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* POST /admin/import - Process import file provided and create bookmarks
|
||||||
|
*/
|
||||||
|
public function import(Request $request, Response $response): Response
|
||||||
|
{
|
||||||
|
$this->checkToken($request);
|
||||||
|
|
||||||
|
$file = ($request->getUploadedFiles() ?? [])['filetoupload'] ?? null;
|
||||||
|
if (!$file instanceof UploadedFileInterface) {
|
||||||
|
$this->saveErrorMessage(t('No import file provided.'));
|
||||||
|
|
||||||
|
return $this->redirect($response, '/admin/import');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Import bookmarks from an uploaded file
|
||||||
|
if (0 === $file->getSize()) {
|
||||||
|
// The file is too big or some form field may be missing.
|
||||||
|
$msg = sprintf(
|
||||||
|
t(
|
||||||
|
'The file you are trying to upload is probably bigger than what this webserver can accept'
|
||||||
|
.' (%s). Please upload in smaller chunks.'
|
||||||
|
),
|
||||||
|
get_max_upload_size(ini_get('post_max_size'), ini_get('upload_max_filesize'))
|
||||||
|
);
|
||||||
|
$this->saveErrorMessage($msg);
|
||||||
|
|
||||||
|
return $this->redirect($response, '/admin/import');
|
||||||
|
}
|
||||||
|
|
||||||
|
$status = $this->container->netscapeBookmarkUtils->import($request->getParams(), $file);
|
||||||
|
|
||||||
|
$this->saveSuccessMessage($status);
|
||||||
|
|
||||||
|
return $this->redirect($response, '/admin/import');
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,6 +6,7 @@
|
||||||
use DateTimeZone;
|
use DateTimeZone;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Katzgrau\KLogger\Logger;
|
use Katzgrau\KLogger\Logger;
|
||||||
|
use Psr\Http\Message\UploadedFileInterface;
|
||||||
use Psr\Log\LogLevel;
|
use Psr\Log\LogLevel;
|
||||||
use Shaarli\Bookmark\Bookmark;
|
use Shaarli\Bookmark\Bookmark;
|
||||||
use Shaarli\Bookmark\BookmarkServiceInterface;
|
use Shaarli\Bookmark\BookmarkServiceInterface;
|
||||||
|
@ -80,19 +81,19 @@ public function filterAndFormat(
|
||||||
* Imports Web bookmarks from an uploaded Netscape bookmark dump
|
* Imports Web bookmarks from an uploaded Netscape bookmark dump
|
||||||
*
|
*
|
||||||
* @param array $post Server $_POST parameters
|
* @param array $post Server $_POST parameters
|
||||||
* @param array $files Server $_FILES parameters
|
* @param UploadedFileInterface $file File in PSR-7 object format
|
||||||
*
|
*
|
||||||
* @return string Summary of the bookmark import status
|
* @return string Summary of the bookmark import status
|
||||||
*/
|
*/
|
||||||
public function import($post, $files)
|
public function import($post, UploadedFileInterface $file)
|
||||||
{
|
{
|
||||||
$start = time();
|
$start = time();
|
||||||
$filename = $files['filetoupload']['name'];
|
$filename = $file->getClientFilename();
|
||||||
$filesize = $files['filetoupload']['size'];
|
$filesize = $file->getSize();
|
||||||
$data = file_get_contents($files['filetoupload']['tmp_name']);
|
$data = (string) $file->getStream();
|
||||||
|
|
||||||
if (preg_match('/<!DOCTYPE NETSCAPE-Bookmark-file-1>/i', $data) === 0) {
|
if (preg_match('/<!DOCTYPE NETSCAPE-Bookmark-file-1>/i', $data) === 0) {
|
||||||
return self::importStatus($filename, $filesize);
|
return $this->importStatus($filename, $filesize);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Overwrite existing bookmarks?
|
// Overwrite existing bookmarks?
|
||||||
|
|
|
@ -40,7 +40,7 @@ http://<replace_domain>/admin/tools
|
||||||
http://<replace_domain>/daily
|
http://<replace_domain>/daily
|
||||||
http://<replace_domain>/?post
|
http://<replace_domain>/?post
|
||||||
http://<replace_domain>/admin/export
|
http://<replace_domain>/admin/export
|
||||||
http://<replace_domain>/?do=import
|
http://<replace_domain>/admin/import
|
||||||
http://<replace_domain>/login
|
http://<replace_domain>/login
|
||||||
http://<replace_domain>/picture-wall
|
http://<replace_domain>/picture-wall
|
||||||
http://<replace_domain>/?do=pluginadmin
|
http://<replace_domain>/?do=pluginadmin
|
||||||
|
|
48
index.php
48
index.php
|
@ -578,51 +578,7 @@ function renderPage($conf, $pluginManager, $bookmarkService, $history, $sessionM
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($targetPage == Router::$PAGE_IMPORT) {
|
if ($targetPage == Router::$PAGE_IMPORT) {
|
||||||
// Upload a Netscape bookmark dump to import its contents
|
header('Location: ./admin/import');
|
||||||
|
|
||||||
if (! isset($_POST['token']) || ! isset($_FILES['filetoupload'])) {
|
|
||||||
// Show import dialog
|
|
||||||
$PAGE->assign(
|
|
||||||
'maxfilesize',
|
|
||||||
get_max_upload_size(
|
|
||||||
ini_get('post_max_size'),
|
|
||||||
ini_get('upload_max_filesize'),
|
|
||||||
false
|
|
||||||
)
|
|
||||||
);
|
|
||||||
$PAGE->assign(
|
|
||||||
'maxfilesizeHuman',
|
|
||||||
get_max_upload_size(
|
|
||||||
ini_get('post_max_size'),
|
|
||||||
ini_get('upload_max_filesize'),
|
|
||||||
true
|
|
||||||
)
|
|
||||||
);
|
|
||||||
$PAGE->assign('pagetitle', t('Import') .' - '. $conf->get('general.title', 'Shaarli'));
|
|
||||||
$PAGE->renderPage('import');
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Import bookmarks from an uploaded file
|
|
||||||
if (isset($_FILES['filetoupload']['size']) && $_FILES['filetoupload']['size'] == 0) {
|
|
||||||
// The file is too big or some form field may be missing.
|
|
||||||
$msg = sprintf(
|
|
||||||
t(
|
|
||||||
'The file you are trying to upload is probably bigger than what this webserver can accept'
|
|
||||||
.' (%s). Please upload in smaller chunks.'
|
|
||||||
),
|
|
||||||
get_max_upload_size(ini_get('post_max_size'), ini_get('upload_max_filesize'))
|
|
||||||
);
|
|
||||||
echo '<script>alert("'. $msg .'");document.location=\'./?do='.Router::$PAGE_IMPORT .'\';</script>';
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
if (! $sessionManager->checkToken($_POST['token'])) {
|
|
||||||
die('Wrong token.');
|
|
||||||
}
|
|
||||||
$netscapeBookmarkUtils = new NetscapeBookmarkUtils($bookmarkService, $conf, $history);
|
|
||||||
$status = $netscapeBookmarkUtils->import($_POST, $_FILES);
|
|
||||||
echo '<script>alert("'.$status.'");document.location=\'./?do='
|
|
||||||
.Router::$PAGE_IMPORT .'\';</script>';
|
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1064,6 +1020,8 @@ function install($conf, $sessionManager, $loginManager)
|
||||||
$this->get('/admin/shaare/{id:[0-9]+}/pin', '\Shaarli\Front\Controller\Admin\ManageShaareController:pinBookmark');
|
$this->get('/admin/shaare/{id:[0-9]+}/pin', '\Shaarli\Front\Controller\Admin\ManageShaareController:pinBookmark');
|
||||||
$this->get('/admin/export', '\Shaarli\Front\Controller\Admin\ExportController:index');
|
$this->get('/admin/export', '\Shaarli\Front\Controller\Admin\ExportController:index');
|
||||||
$this->post('/admin/export', '\Shaarli\Front\Controller\Admin\ExportController:export');
|
$this->post('/admin/export', '\Shaarli\Front\Controller\Admin\ExportController:export');
|
||||||
|
$this->get('/admin/import', '\Shaarli\Front\Controller\Admin\ImportController:index');
|
||||||
|
$this->post('/admin/import', '\Shaarli\Front\Controller\Admin\ImportController:import');
|
||||||
|
|
||||||
$this->get('/links-per-page', '\Shaarli\Front\Controller\Admin\SessionFilterController:linksPerPage');
|
$this->get('/links-per-page', '\Shaarli\Front\Controller\Admin\SessionFilterController:linksPerPage');
|
||||||
$this->get('/visibility/{visibility}', '\Shaarli\Front\Controller\Admin\SessionFilterController:visibility');
|
$this->get('/visibility/{visibility}', '\Shaarli\Front\Controller\Admin\SessionFilterController:visibility');
|
||||||
|
|
|
@ -2,14 +2,12 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace front\controller\admin;
|
namespace Shaarli\Front\Controller\Admin;
|
||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use Shaarli\Bookmark\Bookmark;
|
use Shaarli\Bookmark\Bookmark;
|
||||||
use Shaarli\Formatter\BookmarkFormatter;
|
use Shaarli\Formatter\BookmarkFormatter;
|
||||||
use Shaarli\Formatter\BookmarkRawFormatter;
|
use Shaarli\Formatter\BookmarkRawFormatter;
|
||||||
use Shaarli\Front\Controller\Admin\ExportController;
|
|
||||||
use Shaarli\Front\Controller\Admin\FrontAdminControllerMockHelper;
|
|
||||||
use Shaarli\Netscape\NetscapeBookmarkUtils;
|
use Shaarli\Netscape\NetscapeBookmarkUtils;
|
||||||
use Shaarli\Security\SessionManager;
|
use Shaarli\Security\SessionManager;
|
||||||
use Slim\Http\Request;
|
use Slim\Http\Request;
|
||||||
|
@ -117,7 +115,6 @@ public function testExportSelectionMissing(): void
|
||||||
$request = $this->createMock(Request::class);
|
$request = $this->createMock(Request::class);
|
||||||
$response = new Response();
|
$response = new Response();
|
||||||
|
|
||||||
$this->container->sessionManager = $this->createMock(SessionManager::class);
|
|
||||||
$this->container->sessionManager
|
$this->container->sessionManager
|
||||||
->expects(static::once())
|
->expects(static::once())
|
||||||
->method('setSessionParameter')
|
->method('setSessionParameter')
|
||||||
|
@ -152,7 +149,6 @@ public function testExportErrorEncountered(): void
|
||||||
->willThrowException(new \Exception($message = 'error message'));
|
->willThrowException(new \Exception($message = 'error message'));
|
||||||
;
|
;
|
||||||
|
|
||||||
$this->container->sessionManager = $this->createMock(SessionManager::class);
|
|
||||||
$this->container->sessionManager
|
$this->container->sessionManager
|
||||||
->expects(static::once())
|
->expects(static::once())
|
||||||
->method('setSessionParameter')
|
->method('setSessionParameter')
|
||||||
|
|
148
tests/front/controller/admin/ImportControllerTest.php
Normal file
148
tests/front/controller/admin/ImportControllerTest.php
Normal file
|
@ -0,0 +1,148 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Shaarli\Front\Controller\Admin;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Psr\Http\Message\UploadedFileInterface;
|
||||||
|
use Shaarli\Netscape\NetscapeBookmarkUtils;
|
||||||
|
use Shaarli\Security\SessionManager;
|
||||||
|
use Slim\Http\Request;
|
||||||
|
use Slim\Http\Response;
|
||||||
|
use Slim\Http\UploadedFile;
|
||||||
|
|
||||||
|
class ImportControllerTest extends TestCase
|
||||||
|
{
|
||||||
|
use FrontAdminControllerMockHelper;
|
||||||
|
|
||||||
|
/** @var ImportController */
|
||||||
|
protected $controller;
|
||||||
|
|
||||||
|
public function setUp(): void
|
||||||
|
{
|
||||||
|
$this->createContainer();
|
||||||
|
|
||||||
|
$this->controller = new ImportController($this->container);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test displaying import page
|
||||||
|
*/
|
||||||
|
public function testIndex(): void
|
||||||
|
{
|
||||||
|
$assignedVariables = [];
|
||||||
|
$this->assignTemplateVars($assignedVariables);
|
||||||
|
|
||||||
|
$request = $this->createMock(Request::class);
|
||||||
|
$response = new Response();
|
||||||
|
|
||||||
|
$result = $this->controller->index($request, $response);
|
||||||
|
|
||||||
|
static::assertSame(200, $result->getStatusCode());
|
||||||
|
static::assertSame('import', (string) $result->getBody());
|
||||||
|
|
||||||
|
static::assertSame('Import - Shaarli', $assignedVariables['pagetitle']);
|
||||||
|
static::assertIsInt($assignedVariables['maxfilesize']);
|
||||||
|
static::assertRegExp('/\d+[KM]iB/', $assignedVariables['maxfilesizeHuman']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test importing a file with default and valid parameters
|
||||||
|
*/
|
||||||
|
public function testImportDefault(): void
|
||||||
|
{
|
||||||
|
$parameters = [
|
||||||
|
'abc' => 'def',
|
||||||
|
'other' => 'param',
|
||||||
|
];
|
||||||
|
|
||||||
|
$requestFile = new UploadedFile('file', 'name', 'type', 123);
|
||||||
|
|
||||||
|
$request = $this->createMock(Request::class);
|
||||||
|
$request->method('getParams')->willReturnCallback(function () use ($parameters) {
|
||||||
|
return $parameters;
|
||||||
|
});
|
||||||
|
$request->method('getUploadedFiles')->willReturn(['filetoupload' => $requestFile]);
|
||||||
|
$response = new Response();
|
||||||
|
|
||||||
|
$this->container->netscapeBookmarkUtils = $this->createMock(NetscapeBookmarkUtils::class);
|
||||||
|
$this->container->netscapeBookmarkUtils
|
||||||
|
->expects(static::once())
|
||||||
|
->method('import')
|
||||||
|
->willReturnCallback(
|
||||||
|
function (
|
||||||
|
array $post,
|
||||||
|
UploadedFileInterface $file
|
||||||
|
) use ($parameters, $requestFile): string {
|
||||||
|
static::assertSame($parameters, $post);
|
||||||
|
static::assertSame($requestFile, $file);
|
||||||
|
|
||||||
|
return 'status';
|
||||||
|
}
|
||||||
|
)
|
||||||
|
;
|
||||||
|
|
||||||
|
$this->container->sessionManager
|
||||||
|
->expects(static::once())
|
||||||
|
->method('setSessionParameter')
|
||||||
|
->with(SessionManager::KEY_SUCCESS_MESSAGES, ['status'])
|
||||||
|
;
|
||||||
|
|
||||||
|
$result = $this->controller->import($request, $response);
|
||||||
|
|
||||||
|
static::assertSame(302, $result->getStatusCode());
|
||||||
|
static::assertSame(['/subfolder/admin/import'], $result->getHeader('location'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test posting an import request - without import file
|
||||||
|
*/
|
||||||
|
public function testImportFileMissing(): void
|
||||||
|
{
|
||||||
|
$request = $this->createMock(Request::class);
|
||||||
|
$response = new Response();
|
||||||
|
|
||||||
|
$this->container->sessionManager
|
||||||
|
->expects(static::once())
|
||||||
|
->method('setSessionParameter')
|
||||||
|
->with(SessionManager::KEY_ERROR_MESSAGES, ['No import file provided.'])
|
||||||
|
;
|
||||||
|
|
||||||
|
$result = $this->controller->import($request, $response);
|
||||||
|
|
||||||
|
static::assertSame(302, $result->getStatusCode());
|
||||||
|
static::assertSame(['/subfolder/admin/import'], $result->getHeader('location'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test posting an import request - with an empty file
|
||||||
|
*/
|
||||||
|
public function testImportEmptyFile(): void
|
||||||
|
{
|
||||||
|
$requestFile = new UploadedFile('file', 'name', 'type', 0);
|
||||||
|
|
||||||
|
$request = $this->createMock(Request::class);
|
||||||
|
$request->method('getUploadedFiles')->willReturn(['filetoupload' => $requestFile]);
|
||||||
|
$response = new Response();
|
||||||
|
|
||||||
|
$this->container->netscapeBookmarkUtils = $this->createMock(NetscapeBookmarkUtils::class);
|
||||||
|
$this->container->netscapeBookmarkUtils->expects(static::never())->method('filterAndFormat');
|
||||||
|
|
||||||
|
$this->container->sessionManager
|
||||||
|
->expects(static::once())
|
||||||
|
->method('setSessionParameter')
|
||||||
|
->willReturnCallback(function (string $key, array $value): SessionManager {
|
||||||
|
static::assertSame(SessionManager::KEY_ERROR_MESSAGES, $key);
|
||||||
|
static::assertStringStartsWith('The file you are trying to upload is probably bigger', $value[0]);
|
||||||
|
|
||||||
|
return $this->container->sessionManager;
|
||||||
|
})
|
||||||
|
;
|
||||||
|
|
||||||
|
$result = $this->controller->import($request, $response);
|
||||||
|
|
||||||
|
static::assertSame(302, $result->getStatusCode());
|
||||||
|
static::assertSame(['/subfolder/admin/import'], $result->getHeader('location'));
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,27 +4,28 @@
|
||||||
|
|
||||||
use DateTime;
|
use DateTime;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Psr\Http\Message\UploadedFileInterface;
|
||||||
use Shaarli\Bookmark\Bookmark;
|
use Shaarli\Bookmark\Bookmark;
|
||||||
use Shaarli\Bookmark\BookmarkFileService;
|
use Shaarli\Bookmark\BookmarkFileService;
|
||||||
use Shaarli\Bookmark\BookmarkFilter;
|
use Shaarli\Bookmark\BookmarkFilter;
|
||||||
use Shaarli\Config\ConfigManager;
|
use Shaarli\Config\ConfigManager;
|
||||||
use Shaarli\History;
|
use Shaarli\History;
|
||||||
|
use Slim\Http\UploadedFile;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility function to load a file's metadata in a $_FILES-like array
|
* Utility function to load a file's metadata in a $_FILES-like array
|
||||||
*
|
*
|
||||||
* @param string $filename Basename of the file
|
* @param string $filename Basename of the file
|
||||||
*
|
*
|
||||||
* @return array A $_FILES-like array
|
* @return UploadedFileInterface Upload file in PSR-7 compatible object
|
||||||
*/
|
*/
|
||||||
function file2array($filename)
|
function file2array($filename)
|
||||||
{
|
{
|
||||||
return array(
|
return new UploadedFile(
|
||||||
'filetoupload' => array(
|
__DIR__ . '/input/' . $filename,
|
||||||
'name' => $filename,
|
$filename,
|
||||||
'tmp_name' => __DIR__ . '/input/' . $filename,
|
null,
|
||||||
'size' => filesize(__DIR__ . '/input/' . $filename)
|
filesize(__DIR__ . '/input/' . $filename)
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<body>
|
<body>
|
||||||
{include="page.header"}
|
{include="page.header"}
|
||||||
|
|
||||||
<form method="POST" action="{$base_path}/?do=import" enctype="multipart/form-data" name="uploadform" id="uploadform">
|
<form method="POST" action="{$base_path}/admin/import" enctype="multipart/form-data" name="uploadform" id="uploadform">
|
||||||
<div class="pure-g">
|
<div class="pure-g">
|
||||||
<div class="pure-u-lg-1-4 pure-u-1-24"></div>
|
<div class="pure-u-lg-1-4 pure-u-1-24"></div>
|
||||||
<div class="pure-u-lg-1-2 pure-u-22-24 page-form page-form-complete">
|
<div class="pure-u-lg-1-2 pure-u-22-24 page-form page-form-complete">
|
||||||
|
|
|
@ -33,7 +33,7 @@ <h2 class="window-title">{'Settings'|t}</h2>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="tools-item">
|
<div class="tools-item">
|
||||||
<a href="{$base_path}/?do=import"
|
<a href="{$base_path}/admin/import"
|
||||||
title="{'Import Netscape HTML bookmarks (as exported from Firefox, Chrome, Opera, delicious...)'|t}">
|
title="{'Import Netscape HTML bookmarks (as exported from Firefox, Chrome, Opera, delicious...)'|t}">
|
||||||
<span class="pure-button pure-u-lg-2-3 pure-u-3-4">{'Import links'|t}</span>
|
<span class="pure-button pure-u-lg-2-3 pure-u-3-4">{'Import links'|t}</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
{include="page.header"}
|
{include="page.header"}
|
||||||
<div id="uploaddiv">
|
<div id="uploaddiv">
|
||||||
Import Netscape HTML bookmarks (as exported from Firefox/Chrome/Opera/Delicious/Diigo...) (Max: {$maxfilesize}).
|
Import Netscape HTML bookmarks (as exported from Firefox/Chrome/Opera/Delicious/Diigo...) (Max: {$maxfilesize}).
|
||||||
<form method="POST" action="{$base_path}/?do=import" enctype="multipart/form-data"
|
<form method="POST" action="{$base_path}/admin/import" enctype="multipart/form-data"
|
||||||
name="uploadform" id="uploadform">
|
name="uploadform" id="uploadform">
|
||||||
<input type="hidden" name="token" value="{$token}">
|
<input type="hidden" name="token" value="{$token}">
|
||||||
<input type="hidden" name="MAX_FILE_SIZE" value="{$maxfilesize}">
|
<input type="hidden" name="MAX_FILE_SIZE" value="{$maxfilesize}">
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
<br><br>{/if}
|
<br><br>{/if}
|
||||||
<a href="{$base_path}/admin/tags"><b>Rename/delete tags</b><span>: Rename or delete a tag in all links</span></a>
|
<a href="{$base_path}/admin/tags"><b>Rename/delete tags</b><span>: Rename or delete a tag in all links</span></a>
|
||||||
<br><br>
|
<br><br>
|
||||||
<a href="{$base_path}/?do=import"><b>Import</b><span>: Import Netscape html bookmarks (as exported from Firefox, Chrome, Opera, delicious...)</span></a>
|
<a href="{$base_path}/admin/import"><b>Import</b><span>: Import Netscape html bookmarks (as exported from Firefox, Chrome, Opera, delicious...)</span></a>
|
||||||
<br><br>
|
<br><br>
|
||||||
<a href="{$base_path}/admin/export"><b>Export</b><span>: Export Netscape html bookmarks (which can be imported in Firefox, Chrome, Opera, delicious...)</span></a>
|
<a href="{$base_path}/admin/export"><b>Export</b><span>: Export Netscape html bookmarks (which can be imported in Firefox, Chrome, Opera, delicious...)</span></a>
|
||||||
<br><br>
|
<br><br>
|
||||||
|
|
Loading…
Reference in a new issue