add bookmarks api and iimports, bugfixes

This commit is contained in:
Joey Kimsey
2024-12-07 01:55:13 -05:00
parent dcffa0a7fb
commit 755646ba30
10 changed files with 256 additions and 42 deletions

View File

@ -0,0 +1,59 @@
<?php
/**
* app/plugins/bookmarks/controllers/api/bookmarks.php
*
* This is the api bookmarks controller.
*
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Controllers\Api;
use TheTempusProject\Models\User;
use TheTempusProject\Classes\ApiController;
use TheTempusProject\Houdini\Classes\Views;
use TheTempusProject\Canary\Bin\Canary as Debug;
use TheTempusProject\Bedrock\Functions\Input;
use TheTempusProject\Models\Bookmarks as Bookmark;
class Bookmarks extends ApiController {
protected static $bookmarks;
public function __construct() {
parent::__construct();
self::$bookmarks = new Bookmark;
}
public function create() {
header('Access-Control-Allow-Origin: *');
$user = self::$authToken->createdBy;
$payload = @file_get_contents('php://input');
$payload = json_decode( $payload, true );
Debug::error($payload['name']);
$result = self::$bookmarks->create(
$payload['name'],
$payload['url'],
0,
$payload['notes'],
'default',
'private',
'external',
$user
);
if ( ! $result ) {
$responseType = 'error';
$response = 'There was an error creating your bookmark.';
} else {
$responseType = 'success';
$response = 'success';
}
Views::view( 'api.response', ['response' => json_encode( [ $responseType => $response ], true )]);
}
}

View File

@ -108,7 +108,6 @@ class Bookmarks extends Controller {
}
Navigation::setCrumbComponent( 'BookmarkBreadCrumbs', 'bookmarks/bookmarks/' . $id );
$bookmarks = self::$bookmarks->noFolder();
$panelArray = [];
@ -399,4 +398,118 @@ class Bookmarks extends Controller {
Session::flash( 'success', 'Bookmark data refreshed.' );
return Redirect::to( 'bookmarks/bookmark/' . $bookmark->ID );
}
public function import() {
// echo '<pre>';
if ( ! Input::exists('submit') ) {
return Views::view( 'bookmarks.import' );
}
if ( ! Forms::check( 'importBookmarks' ) ) {
Issues::add( 'error', [ 'There was an error importing your bookmarks.' => Check::userErrors() ] );
return Views::view( 'bookmarks.import' );
}
if (isset($_FILES['bookmark_file'])) {
$file = $_FILES['bookmark_file'];
// Check file size
if ($file['size'] > 1024 * 1024) { // 1024 KB = 1 MB
die('The file is too large. Maximum size is 1 MB.');
}
// Check file extension
$fileExtension = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
if ($fileExtension !== 'html') {
die('Invalid file type. Only .html files are allowed.');
}
// Proceed with file processing
$fileContent = file_get_contents($file['tmp_name']);
} else {
die('No file was uploaded.');
}
$out = $this->parseBookmarks($fileContent);
$date = 'today';
$description = 'Imported on ' . $date . ' from file: ' . $file['name'];
$importFolder = self::$folders->create( 'New Import', 0, $description );
// $importFolder = 1;
// echo 'make import folder: ' . PHP_EOL;
foreach ($out as $folder => $bookmarks) {
// echo 'make folder: ' . $folder . PHP_EOL;
$currentFolder = self::$folders->create( $folder, $importFolder, $description );
foreach ($bookmarks as $index => $bookmark) {
// echo 'make folder: ' . $bookmark['url'] . PHP_EOL;
self::$bookmarks->create( $bookmark['name'], $bookmark['url'], $currentFolder);
}
}
Session::flash( 'success', 'Your Bookmark has been created.' );
Redirect::to( 'bookmarks/bookmarks/'. $importFolder );
// echo '</pre>';
// exit;
// dv ( $out );
}
public function parseBookmarks($htmlContent)
{
$started = false;
$out = [];
$currentFolder = [];
$folderName = ['unknown'];
$lines = explode("\n", $htmlContent);
foreach ($lines as $line) {
if ( $started == false ) {
if (preg_match("/<h1>(.*?)<\/h1>/i", $line, $matches)) {
$started = true;
}
continue;
}
if (preg_match('/<DL><p>/i', $line, $matches)) {
continue;
}
if (preg_match('/<H3(.*)>(.*?)<\/h3>/i', $line, $matches)) {
$newFolder = $matches[2];
$out[$newFolder] = [];
array_unshift($folderName, $newFolder );
continue;
}
if (preg_match('/<\/DL><p>/i', $line, $matches)) {
array_shift($folderName);
continue;
}
if (preg_match('/<A HREF="(.*?)"(.*)>(.*?)<\/A>/i', $line, $matches)) {
$href = $matches[1];
$guts = $matches[2];
$text = $matches[3];
$added = '';
$icon = '';
if (preg_match('/ADD_DATE="(.*?)"/i', $guts, $addMatches)) {
$added = $addMatches[1];
}
if (preg_match('/ICON="(.*?)"/i', $guts, $iconMatches)) {
$icon = $iconMatches[1];
}
$currentFolder = $folderName[0];
$out[$currentFolder][] = [
'name' => $text,
'url' => $href,
'addDate' => $added,
'icon' => $icon,
'folderName' => $folderName[0],
];
continue;
}
}
return $out;
}
}

View File

@ -25,6 +25,7 @@ class BookmarksForms extends Forms {
self::addHandler( 'createFolder', __CLASS__, 'createFolder' );
self::addHandler( 'editBookmark', __CLASS__, 'editBookmark' );
self::addHandler( 'editFolder', __CLASS__, 'editFolder' );
self::addHandler( 'importBookmarks', __CLASS__, 'importBookmarks' );
}
public static function createBookmark() {
@ -117,6 +118,29 @@ class BookmarksForms extends Forms {
// }
return true;
}
public static function importBookmarks() {
if ( ! Input::exists( 'submit' ) ) {
return false;
}
// if ( ! Input::exists( 'title' ) ) {
// Check::addUserError( 'You must include a title.' );
// return false;
// }
// if ( ! Input::exists( 'color' ) ) {
// Check::addUserError( 'You must include a color.' );
// return false;
// }
// if ( ! Input::exists( 'privacy' ) ) {
// Check::addUserError( 'You must include a privacy.' );
// return false;
// }
// if ( !self::token() ) {
// Check::addUserError( 'token - comment out later.' );
// return false;
// }
return true;
}
}
new BookmarksForms;

View File

@ -51,14 +51,17 @@ class Bookmarks extends DatabaseModel {
parent::__construct();
}
public function create( $title, $url, $folderID = 0, $description = '', $color = 'default', $privacy = 'private', $type = 'external' ) {
public function create( $title, $url, $folderID = 0, $description = '', $color = 'default', $privacy = 'private', $type = 'external', $user = null ) {
if ( empty( $user ) ) {
$user = App::$activeUser->ID;
}
$fields = [
'title' => $title,
'url' => $url,
'description' => $description,
'color' => $color,
'privacy' => $privacy,
'createdBy' => App::$activeUser->ID,
'createdBy' => $user,
'createdAt' => time(),
];
if ( !empty( $folderID ) ) {
@ -676,8 +679,11 @@ class Bookmarks extends DatabaseModel {
}
private function getBaseUrl ( $url ) {
$parsedUrl = parse_url($url);
if ( empty($url) ) {
return $url;
}
$parsedUrl = parse_url($url);
if (isset($parsedUrl['scheme']) && isset($parsedUrl['host'])) {
return $parsedUrl['scheme'] . '://' . $parsedUrl['host'] . '/';
} else {

View File

@ -20,7 +20,7 @@
<td style="text-align: center;">
{privacy}
</td>
<td><a href="{ROOT_URL}bookmarks/bookmarks/{ID}" class="btn btn-sm btn-primary" role="button"><i class="glyphicon glyphicon-open"></i></a></td>
<td><a href="{ROOT_URL}bookmarks/bookmark/{ID}" class="btn btn-sm btn-primary" role="button"><i class="glyphicon glyphicon-open"></i></a></td>
<td><a href="{ROOT_URL}bookmarks/editBookmark/{ID}" class="btn btn-sm btn-warning" role="button"><i class="glyphicon glyphicon-edit"></i></a></td>
<td><a href="{ROOT_URL}bookmarks/deleteBookmark/{ID}" class="btn btn-sm btn-danger" role="button"><i class="glyphicon glyphicon-trash"></i></a></td>
</tr>

View File

@ -0,0 +1,16 @@
<legend>Import Bookmarks</legend>
<form action="" method="post" enctype="multipart/form-data" class="form-horizontal">
<div class="form-group">
<label for="bookmark_file" class="col-lg-3 control-label">Export file (.html):</label>
<div class="col-lg-3">
<input type="file" name="bookmark_file" id="bookmark_file" accept=".html">
</div>
</div>
<div class="form-group">
<label for="submit" class="col-lg-3 control-label"></label>
<div class="col-lg-3">
<button name="submit" value="submit" type="submit" class="btn btn-lg btn-primary center-block ">Import</button>
</div>
</div>
</form>

View File

@ -1,5 +1,6 @@
<ul class="nav nav-tabs">
<li><a href="{ROOT_URL}bookmarks/index/">Dashboard</a></li>
<li><a href="{ROOT_URL}bookmarks/folders/">Folders</a></li>
<li><a href="{ROOT_URL}bookmarks/import/">Import</a></li>
</ul>
{userFolderTabs}

View File

@ -14,20 +14,20 @@ namespace TheTempusProject\Controllers\Api;
use Stripe\StripeClient;
use Stripe\Event;
use TheTempusProject\Models\User;
use TheTempusProject\Controllers\StripeApiController;
use TheTempusProject\Controllers\ApiController;
use TheTempusProject\Houdini\Classes\Views;
use TheTempusProject\Bedrock\Classes\Config;
use TheTempusProject\Canary\Bin\Canary as Debug;
use TheTempusProject\Models\MembershipCustomers;
use TheTempusProject\Models\Memberships;
class Stripe extends StripeApiController {
class Stripe extends ApiController {
public static $stripe;
public static $customers;
public static $memberships;
public function __construct() {
parent::__construct();
parent::__construct( false );
$api_key = Config::getValue( 'memberships/stripeSecret' );
self::$stripe = new StripeClient($api_key);
}

View File

@ -1,33 +0,0 @@
<?php
/**
* app/classes/admin_controller.php
*
* This is the base admin controller. Every other admin controller should
* extend this class.
*
* @version 3.0
* @author Joey Kimsey <Joey@thetempusproject.com>
* @link https://TheTempusProject.com
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
namespace TheTempusProject\Controllers;
use TheTempusProject\Houdini\Classes\Template;
use TheTempusProject\TheTempusProject as App;
use TheTempusProject\Hermes\Functions\Redirect;
use TheTempusProject\Bedrock\Functions\Session;
use TheTempusProject\Classes\Controller;
class StripeApiController extends Controller {
public function __construct() {
parent::__construct();
// if ( ! App::verifyApiRequest() ) {
// Session::flash( 'error', 'You do not have permission to view this page.' );
// return Redirect::home();
// }
Template::noFollow();
Template::noIndex();
Template::addHeader( 'Content-Type: application/json; charset=utf-8' );
Template::setTemplate( 'api' );
}
}

View File

@ -69,3 +69,31 @@
</div>
</div>
</div>
https://www.bookmarkninja.com/
simple robust versatile
sleek
clean
intuitive
modern
A cleaner app for managing bookmarks to cut down on the clutter
Available accross all devices and systems.
regardless of windows or mac, android or apple, wwe have you covered
bring all your bookmarks at once, simply export from your current browser and use our import tool
stop straining your eyes! Not only can you use our dark mode feature, but we have several styles to choose from to customize your experience
no mobile app necessary
privacy is key! but sharing is ok
by defaults everything is set to private, but usiing the web interface will alow you to share single links or entire lists/folders