From 755646ba3028a2e2881fc785a4f19d9fe0e36962 Mon Sep 17 00:00:00 2001 From: Joey Kimsey Date: Sat, 7 Dec 2024 01:55:13 -0500 Subject: [PATCH] add bookmarks api and iimports, bugfixes --- .../bookmarks/controllers/api/bookmarks.php | 59 +++++++++ .../bookmarks/controllers/bookmarks.php | 115 +++++++++++++++++- app/plugins/bookmarks/forms.php | 24 ++++ app/plugins/bookmarks/models/bookmarks.php | 14 ++- .../bookmarks/views/bookmarks/list.html | 2 +- app/plugins/bookmarks/views/import.html | 16 +++ .../bookmarks/views/nav/folderTabs.html | 1 + .../members/controllers/api/stripe.php | 6 +- .../controllers/stripe_api_controller.php | 33 ----- app/views/index.html | 28 +++++ 10 files changed, 256 insertions(+), 42 deletions(-) create mode 100644 app/plugins/bookmarks/controllers/api/bookmarks.php create mode 100644 app/plugins/bookmarks/views/import.html delete mode 100644 app/plugins/members/controllers/stripe_api_controller.php diff --git a/app/plugins/bookmarks/controllers/api/bookmarks.php b/app/plugins/bookmarks/controllers/api/bookmarks.php new file mode 100644 index 0000000..fbbfc32 --- /dev/null +++ b/app/plugins/bookmarks/controllers/api/bookmarks.php @@ -0,0 +1,59 @@ + + * @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 )]); + } +} + diff --git a/app/plugins/bookmarks/controllers/bookmarks.php b/app/plugins/bookmarks/controllers/bookmarks.php index 3641faa..0f2595c 100644 --- a/app/plugins/bookmarks/controllers/bookmarks.php +++ b/app/plugins/bookmarks/controllers/bookmarks.php @@ -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 '
';
+        
+        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 '
'; + // 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>/i", $line, $matches)) { + $started = true; + } + continue; + } + + if (preg_match('/

/i', $line, $matches)) { + continue; + } + + if (preg_match('/(.*?)<\/h3>/i', $line, $matches)) { + $newFolder = $matches[2]; + $out[$newFolder] = []; + array_unshift($folderName, $newFolder ); + continue; + } + + if (preg_match('/<\/DL>

/i', $line, $matches)) { + array_shift($folderName); + continue; + } + + if (preg_match('/(.*?)<\/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; + } } diff --git a/app/plugins/bookmarks/forms.php b/app/plugins/bookmarks/forms.php index d0fd2b5..a42c6b7 100644 --- a/app/plugins/bookmarks/forms.php +++ b/app/plugins/bookmarks/forms.php @@ -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; \ No newline at end of file diff --git a/app/plugins/bookmarks/models/bookmarks.php b/app/plugins/bookmarks/models/bookmarks.php index 39b77f3..d514221 100644 --- a/app/plugins/bookmarks/models/bookmarks.php +++ b/app/plugins/bookmarks/models/bookmarks.php @@ -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 ) ) { @@ -675,9 +678,12 @@ class Bookmarks extends DatabaseModel { return true; } - private function getBaseUrl ($url ) { - $parsedUrl = parse_url($url); + private function getBaseUrl ( $url ) { + if ( empty($url) ) { + return $url; + } + $parsedUrl = parse_url($url); if (isset($parsedUrl['scheme']) && isset($parsedUrl['host'])) { return $parsedUrl['scheme'] . '://' . $parsedUrl['host'] . '/'; } else { diff --git a/app/plugins/bookmarks/views/bookmarks/list.html b/app/plugins/bookmarks/views/bookmarks/list.html index 32b8a5e..716baff 100644 --- a/app/plugins/bookmarks/views/bookmarks/list.html +++ b/app/plugins/bookmarks/views/bookmarks/list.html @@ -20,7 +20,7 @@ {privacy} - + diff --git a/app/plugins/bookmarks/views/import.html b/app/plugins/bookmarks/views/import.html new file mode 100644 index 0000000..7611a76 --- /dev/null +++ b/app/plugins/bookmarks/views/import.html @@ -0,0 +1,16 @@ +Import Bookmarks +

+
+ +
+ +
+
+ +
+ +
+ +
+
+
\ No newline at end of file diff --git a/app/plugins/bookmarks/views/nav/folderTabs.html b/app/plugins/bookmarks/views/nav/folderTabs.html index 2ab6a13..7000c00 100644 --- a/app/plugins/bookmarks/views/nav/folderTabs.html +++ b/app/plugins/bookmarks/views/nav/folderTabs.html @@ -1,5 +1,6 @@ {userFolderTabs} \ No newline at end of file diff --git a/app/plugins/members/controllers/api/stripe.php b/app/plugins/members/controllers/api/stripe.php index 4f08745..3bf3ce9 100644 --- a/app/plugins/members/controllers/api/stripe.php +++ b/app/plugins/members/controllers/api/stripe.php @@ -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); } diff --git a/app/plugins/members/controllers/stripe_api_controller.php b/app/plugins/members/controllers/stripe_api_controller.php deleted file mode 100644 index 1e8a4ad..0000000 --- a/app/plugins/members/controllers/stripe_api_controller.php +++ /dev/null @@ -1,33 +0,0 @@ - - * @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' ); - } -} diff --git a/app/views/index.html b/app/views/index.html index eddb234..26a7369 100644 --- a/app/views/index.html +++ b/app/views/index.html @@ -69,3 +69,31 @@ + +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 +