Initial commit
This commit is contained in:
705
app/plugins/bookmarks/models/bookmarks.php
Normal file
705
app/plugins/bookmarks/models/bookmarks.php
Normal file
@ -0,0 +1,705 @@
|
||||
<?php
|
||||
/**
|
||||
* app/plugins/bookmarks/models/bookmarks.php
|
||||
*
|
||||
* This class is used for the manipulation of the bookmarks database table.
|
||||
*
|
||||
* @package TP Bookmarks
|
||||
* @version 3.0
|
||||
* @author Joey Kimsey <Joey@thetempusproject.com>
|
||||
* @link https://TheTempusProject.com
|
||||
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
|
||||
*/
|
||||
namespace TheTempusProject\Models;
|
||||
|
||||
use TheTempusProject\Bedrock\Classes\Config;
|
||||
use TheTempusProject\Bedrock\Functions\Check;
|
||||
use TheTempusProject\Canary\Canary as Debug;
|
||||
use TheTempusProject\Classes\DatabaseModel;
|
||||
use TheTempusProject\TheTempusProject as App;
|
||||
use TheTempusProject\Houdini\Classes\Filters;
|
||||
use TheTempusProject\Bedrock\Classes\CustomException;
|
||||
|
||||
class Bookmarks extends DatabaseModel {
|
||||
public $tableName = 'bookmarks';
|
||||
public $linkTypes = [
|
||||
'Open in New Tab' => 'external',
|
||||
'Open in Same Tab' => 'internal',
|
||||
];
|
||||
|
||||
public $databaseMatrix = [
|
||||
[ 'title', 'varchar', '256' ],
|
||||
[ 'url', 'text', '' ],
|
||||
[ 'color', 'varchar', '48' ],
|
||||
[ 'privacy', 'varchar', '48' ],
|
||||
[ 'folderID', 'int', '11' ],
|
||||
[ 'description', 'text', '' ],
|
||||
[ 'createdBy', 'int', '11' ],
|
||||
[ 'createdAt', 'int', '11' ],
|
||||
[ 'meta', 'text', '' ],
|
||||
[ 'icon', 'text', '' ],
|
||||
[ 'archivedAt', 'int', '11' ],
|
||||
[ 'refreshedAt', 'int', '11' ],
|
||||
[ 'hiddenAt', 'int', '11' ],
|
||||
[ 'order', 'int', '11' ],
|
||||
[ 'linkType', 'varchar', '32' ],
|
||||
];
|
||||
|
||||
/**
|
||||
* The model constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function create( $title, $url, $folderID = 0, $description = '', $color = 'default', $privacy = 'private', $type = 'external' ) {
|
||||
$fields = [
|
||||
'title' => $title,
|
||||
'url' => $url,
|
||||
'description' => $description,
|
||||
'color' => $color,
|
||||
'privacy' => $privacy,
|
||||
'createdBy' => App::$activeUser->ID,
|
||||
'createdAt' => time(),
|
||||
];
|
||||
if ( !empty( $folderID ) ) {
|
||||
$fields['folderID'] = $folderID;
|
||||
} else {
|
||||
$fields['folderID'] = null;
|
||||
}
|
||||
if ( ! self::$db->insert( $this->tableName, $fields ) ) {
|
||||
new CustomException( 'bookmarkCreate' );
|
||||
Debug::error( "Bookmarks: not created " . var_export($fields,true) );
|
||||
return false;
|
||||
}
|
||||
return self::$db->lastId();
|
||||
}
|
||||
|
||||
public function update( $id, $title, $url, $folderID = 0, $description = '', $color = 'default', $privacy = 'private', $type = 'external', $order = 0 ) {
|
||||
if ( !Check::id( $id ) ) {
|
||||
Debug::info( 'Bookmarks: illegal ID.' );
|
||||
return false;
|
||||
}
|
||||
$fields = [
|
||||
'title' => $title,
|
||||
'url' => $url,
|
||||
'description' => $description,
|
||||
'color' => $color,
|
||||
'privacy' => $privacy,
|
||||
// 'linkType' => $type,
|
||||
// 'order' => $order,
|
||||
];
|
||||
if ( !empty( $folderID ) ) {
|
||||
$fields['folderID'] = $folderID;
|
||||
}
|
||||
if ( !self::$db->update( $this->tableName, $id, $fields ) ) {
|
||||
new CustomException( 'bookmarkUpdate' );
|
||||
Debug::error( "Bookmarks: $id not updated" );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function byUser( $limit = null ) {
|
||||
$whereClause = ['createdBy', '=', App::$activeUser->ID];
|
||||
if ( empty( $limit ) ) {
|
||||
$bookmarks = self::$db->get( $this->tableName, $whereClause );
|
||||
} else {
|
||||
$bookmarks = self::$db->get( $this->tableName, $whereClause, 'ID', 'DESC', [0, $limit] );
|
||||
}
|
||||
if ( !$bookmarks->count() ) {
|
||||
Debug::info( 'No Bookmarks found.' );
|
||||
return false;
|
||||
}
|
||||
return $this->filter( $bookmarks->results() );
|
||||
}
|
||||
|
||||
public function byFolder( $id, $limit = null ) {
|
||||
$whereClause = ['createdBy', '=', App::$activeUser->ID, 'AND'];
|
||||
|
||||
$whereClause = array_merge( $whereClause, [ 'folderID', '=', $id ] );
|
||||
if ( empty( $limit ) ) {
|
||||
$bookmarks = self::$db->get( $this->tableName, $whereClause );
|
||||
} else {
|
||||
$bookmarks = self::$db->get( $this->tableName, $whereClause, 'ID', 'DESC', [0, $limit] );
|
||||
}
|
||||
if ( !$bookmarks->count() ) {
|
||||
Debug::info( 'No Bookmarks found.' );
|
||||
return false;
|
||||
}
|
||||
return $this->filter( $bookmarks->results() );
|
||||
}
|
||||
|
||||
public function noFolder( $id = 0, $limit = 10 ) {
|
||||
$whereClause = ['createdBy', '=', App::$activeUser->ID, 'AND'];
|
||||
if ( !empty( $id ) ) {
|
||||
$whereClause = array_merge( $whereClause, ['folderID', '!=', $id] );
|
||||
} else {
|
||||
$whereClause = array_merge( $whereClause, [ 'folderID', 'IS', null] );
|
||||
}
|
||||
if ( empty( $limit ) ) {
|
||||
$bookmarks = self::$db->get( $this->tableName, $whereClause );
|
||||
} else {
|
||||
$bookmarks = self::$db->get( $this->tableName, $whereClause, 'ID', 'DESC', [ 0, $limit ] );
|
||||
}
|
||||
if ( !$bookmarks->count() ) {
|
||||
Debug::info( 'No Bookmarks found.' );
|
||||
return false;
|
||||
}
|
||||
return $this->filter( $bookmarks->results() );
|
||||
}
|
||||
|
||||
public function getName( $id ) {
|
||||
$bookmarks = self::findById( $id );
|
||||
if (false == $bookmarks) {
|
||||
return 'unknown';
|
||||
}
|
||||
return $bookmarks->title;
|
||||
}
|
||||
|
||||
public function getColor( $id ) {
|
||||
$bookmarks = self::findById( $id );
|
||||
if (false == $bookmarks) {
|
||||
return 'default';
|
||||
}
|
||||
return $bookmarks->color;
|
||||
}
|
||||
|
||||
public function simpleByUser() {
|
||||
$whereClause = ['createdBy', '=', App::$activeUser->ID];
|
||||
$bookmarks = self::$db->get( $this->tableName, $whereClause );
|
||||
if ( !$bookmarks->count() ) {
|
||||
Debug::warn( 'Could not find any bookmarks' );
|
||||
return false;
|
||||
}
|
||||
|
||||
$bookmarks = $bookmarks->results();
|
||||
$out = [];
|
||||
foreach ( $bookmarks as $bookmarks ) {
|
||||
$out[ $bookmarks->title ] = $bookmarks->ID;
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
public function simpleObjectByUser() {
|
||||
$whereClause = ['createdBy', '=', App::$activeUser->ID];
|
||||
$bookmarks = self::$db->get( $this->tableName, $whereClause );
|
||||
if ( !$bookmarks->count() ) {
|
||||
Debug::warn( 'Could not find any bookmarks' );
|
||||
return false;
|
||||
}
|
||||
|
||||
$bookmarks = $bookmarks->results();
|
||||
$out = [];
|
||||
foreach ( $bookmarks as $bookmarks ) {
|
||||
$obj = new \stdClass();
|
||||
$obj->title = $bookmarks->title;
|
||||
$obj->ID = $bookmarks->ID;
|
||||
$out[] = $obj;
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
public function deleteByFolder( $folderID ) {
|
||||
$whereClause = [ 'createdBy', '=', App::$activeUser->ID, 'AND' ];
|
||||
$whereClause = array_merge( $whereClause, [ 'folderID', '=', $folderID ] );
|
||||
$bookmarks = self::$db->get( $this->tableName, $whereClause );
|
||||
if ( ! $bookmarks->count() ) {
|
||||
Debug::info( 'No ' . $this->tableName . ' data found.' );
|
||||
return [];
|
||||
}
|
||||
foreach( $bookmarks->results() as $bookmark ) {
|
||||
$this->delete( $bookmark->ID );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private function resolveShortenedUrl( $url ) {
|
||||
$ch = curl_init($url);
|
||||
|
||||
// Set curl options
|
||||
curl_setopt($ch, CURLOPT_NOBODY, true); // We don't need the body
|
||||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // Follow redirects
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // Return the response
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 30); // Set a timeout
|
||||
// curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); // Maybe sketchy?
|
||||
// Maybe sketchy?
|
||||
// curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // Disable SSL host verification
|
||||
// curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // Disable SSL peer verification
|
||||
// curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);
|
||||
|
||||
// added to support the regex site
|
||||
// curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
|
||||
|
||||
// =
|
||||
// curl_setopt($ch, CURLOPT_SSL_CIPHER_LIST, 'AES256+EECDH:AES256+EDH' );
|
||||
|
||||
|
||||
|
||||
|
||||
// Execute curl
|
||||
$response = curl_exec( $ch );
|
||||
|
||||
// Check if there was an error
|
||||
if ( curl_errno( $ch ) ) {
|
||||
|
||||
|
||||
// Get error details
|
||||
$errorCode = curl_errno($ch);
|
||||
$errorMessage = curl_error($ch);
|
||||
// Log or display the error details
|
||||
dv('cURL Error: ' . $errorMessage . ' (Error Code: ' . $errorCode . ')');
|
||||
|
||||
curl_close($ch);
|
||||
// return $url; // Return the original URL if there was an error
|
||||
|
||||
|
||||
$url = rtrim( $url, '/' );
|
||||
$ch2 = curl_init($url);
|
||||
curl_setopt($ch2, CURLOPT_NOBODY, true); // We don't need the body
|
||||
curl_setopt($ch2, CURLOPT_FOLLOWLOCATION, true); // Follow redirects
|
||||
curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true); // Return the response
|
||||
curl_setopt($ch2, CURLOPT_TIMEOUT, 5); // Set a timeout
|
||||
curl_exec($ch2);
|
||||
|
||||
if ( curl_errno( $ch2 ) ) {
|
||||
|
||||
}
|
||||
curl_close( $ch );
|
||||
return $url;
|
||||
}
|
||||
|
||||
// Get the effective URL (the final destination after redirects)
|
||||
$finalUrl = curl_getinfo( $ch, CURLINFO_EFFECTIVE_URL );
|
||||
curl_close( $ch );
|
||||
|
||||
return $finalUrl;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// $headers = get_headers( $url, 1 );
|
||||
$headers = @get_headers($url, 1);
|
||||
if ( $headers === false ) {
|
||||
}
|
||||
if ( isset( $headers['Location'] ) ) {
|
||||
if (is_array($headers['Location'])) {
|
||||
return end($headers['Location']);
|
||||
} else {
|
||||
return $headers['Location'];
|
||||
}
|
||||
} else {
|
||||
return $url;
|
||||
}
|
||||
}
|
||||
|
||||
public function filter( $data, $params = [] ) {
|
||||
foreach ( $data as $instance ) {
|
||||
if ( !is_object( $instance ) ) {
|
||||
$instance = $data;
|
||||
$end = true;
|
||||
}
|
||||
$base_url = $this->getBaseUrl( $instance->url );
|
||||
|
||||
if ( empty( $instance->icon ) ) {
|
||||
$instance->iconHtml = '<i class="glyphicon glyphicon-link"></i>';
|
||||
} else {
|
||||
if (strpos($instance->icon, 'http') !== false) {
|
||||
$instance->iconHtml = '<img src="' . $instance->icon .'" />';
|
||||
} else {
|
||||
$instance->iconHtml = '<img src="' . $base_url . ltrim( $instance->icon, '/' ) .'" />';
|
||||
}
|
||||
}
|
||||
if ( empty( $instance->hiddenAt ) ) {
|
||||
$instance->hideBtn = '
|
||||
<a href="{ROOT_URL}bookmarks/hideBookmark/'.$instance->ID.'" class="btn btn-sm btn-warning" role="button">
|
||||
<i class="glyphicon glyphicon-eye-open"></i>
|
||||
</a>';
|
||||
} else {
|
||||
$instance->hideBtn = '
|
||||
<a href="{ROOT_URL}bookmarks/showBookmark/'.$instance->ID.'" class="btn btn-sm btn-default" role="button">
|
||||
<i class="glyphicon glyphicon-eye-open"></i>
|
||||
</a>';
|
||||
}
|
||||
if ( empty( $instance->archivedAt ) ) {
|
||||
$instance->archiveBtn = '
|
||||
<a href="{ROOT_URL}bookmarks/archiveBookmark/'.$instance->ID.'" class="btn btn-sm btn-info" role="button">
|
||||
<i class="glyphicon glyphicon-briefcase"></i>
|
||||
</a>';
|
||||
} else {
|
||||
$instance->archiveBtn = '
|
||||
<a href="{ROOT_URL}bookmarks/unarchiveBookmark/'.$instance->ID.'" class="btn btn-sm btn-default" role="button">
|
||||
<i class="glyphicon glyphicon-briefcase"></i>
|
||||
</a>';
|
||||
}
|
||||
if ( ! empty( $instance->refreshedAt ) && time() < ( $instance->refreshedAt + ( 60 * 10 ) ) ) {
|
||||
$instance->refreshBtn = '
|
||||
<a href="{ROOT_URL}bookmarks/refreshBookmark/'.$instance->ID.'" class="btn btn-sm btn-danger" role="button">
|
||||
<i class="glyphicon glyphicon-refresh"></i>
|
||||
</a>';
|
||||
} else {
|
||||
$instance->refreshBtn = '
|
||||
<a href="{ROOT_URL}bookmarks/refreshBookmark/'.$instance->ID.'" class="btn btn-sm btn-success" role="button">
|
||||
<i class="glyphicon glyphicon-refresh"></i>
|
||||
</a>';
|
||||
}
|
||||
|
||||
$out[] = $instance;
|
||||
if ( !empty( $end ) ) {
|
||||
$out = $out[0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
public function hide( $id ) {
|
||||
if ( !Check::id( $id ) ) {
|
||||
Debug::info( 'Bookmarks: illegal ID.' );
|
||||
return false;
|
||||
}
|
||||
$fields = [
|
||||
'hiddenAt' => time(),
|
||||
];
|
||||
if ( !self::$db->update( $this->tableName, $id, $fields ) ) {
|
||||
new CustomException( 'bookmarkUpdate' );
|
||||
Debug::error( "Bookmarks: $id not updated" );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function show( $id ) {
|
||||
if ( !Check::id( $id ) ) {
|
||||
Debug::info( 'Bookmarks: illegal ID.' );
|
||||
return false;
|
||||
}
|
||||
$fields = [
|
||||
'hiddenAt' => 0,
|
||||
];
|
||||
if ( !self::$db->update( $this->tableName, $id, $fields ) ) {
|
||||
new CustomException( 'bookmarkUpdate' );
|
||||
Debug::error( "Bookmarks: $id not updated" );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function archive( $id ) {
|
||||
if ( !Check::id( $id ) ) {
|
||||
Debug::info( 'Bookmarks: illegal ID.' );
|
||||
return false;
|
||||
}
|
||||
$fields = [
|
||||
'archivedAt' => time(),
|
||||
];
|
||||
if ( !self::$db->update( $this->tableName, $id, $fields ) ) {
|
||||
new CustomException( 'bookmarkUpdate' );
|
||||
Debug::error( "Bookmarks: $id not updated" );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function unarchive( $id ) {
|
||||
if ( !Check::id( $id ) ) {
|
||||
Debug::info( 'Bookmarks: illegal ID.' );
|
||||
return false;
|
||||
}
|
||||
$fields = [
|
||||
'archivedAt' => 0,
|
||||
];
|
||||
if ( !self::$db->update( $this->tableName, $id, $fields ) ) {
|
||||
new CustomException( 'bookmarkUpdate' );
|
||||
Debug::error( "Bookmarks: $id not updated" );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function extractMetaTags($htmlContent) {
|
||||
$doc = new \DOMDocument();
|
||||
@$doc->loadHTML($htmlContent);
|
||||
$metaTags = [];
|
||||
foreach ($doc->getElementsByTagName('meta') as $meta) {
|
||||
$name = $meta->getAttribute('name') ?: $meta->getAttribute('property');
|
||||
$content = $meta->getAttribute('content');
|
||||
if ($name && $content) {
|
||||
$metaTags[$name] = $content;
|
||||
}
|
||||
}
|
||||
return $metaTags;
|
||||
}
|
||||
|
||||
public function fetchUrlData($url) {
|
||||
$ch = curl_init();
|
||||
|
||||
// Set cURL options
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_HEADER, true); // Include headers in the output
|
||||
curl_setopt($ch, CURLOPT_NOBODY, false); // Include the body in the output
|
||||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // Follow redirects
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 30); // Set a timeout
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // Disable SSL host verification for testing
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // Disable SSL peer verification for testing
|
||||
|
||||
// Execute cURL request
|
||||
$response = curl_exec($ch);
|
||||
|
||||
// Check if there was an error
|
||||
if (curl_errno($ch)) {
|
||||
$errorMessage = curl_error($ch);
|
||||
curl_close($ch);
|
||||
throw new \Exception('cURL Error: ' . $errorMessage);
|
||||
}
|
||||
|
||||
// Get HTTP status code
|
||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
|
||||
// Separate headers and body
|
||||
$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
|
||||
$headers = substr($response, 0, $headerSize);
|
||||
$body = substr($response, $headerSize);
|
||||
|
||||
curl_close($ch);
|
||||
|
||||
// Parse headers into an associative array
|
||||
$headerLines = explode("\r\n", trim($headers));
|
||||
$headerArray = [];
|
||||
foreach ($headerLines as $line) {
|
||||
$parts = explode(': ', $line, 2);
|
||||
if (count($parts) == 2) {
|
||||
$headerArray[$parts[0]] = $parts[1];
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'http_code' => $httpCode,
|
||||
'headers' => $headerArray,
|
||||
'body' => $body,
|
||||
];
|
||||
}
|
||||
|
||||
private function getMetaTagsAndFavicon( $url ) {
|
||||
try {
|
||||
// $url = 'https://runescape.wiki';
|
||||
$data = $this->fetchUrlData($url);
|
||||
|
||||
// iv($data);
|
||||
|
||||
// Get headers
|
||||
$headers = $data['headers'];
|
||||
iv($headers);
|
||||
|
||||
// Get meta tags
|
||||
$metaTags = $this->extractMetaTags($data['body']);
|
||||
} catch (Exception $e) {
|
||||
dv( 'Error: ' . $e->getMessage());
|
||||
|
||||
}
|
||||
$metaInfo = [
|
||||
'url' => $url,
|
||||
'title' => null,
|
||||
'description' => null,
|
||||
'image' => null,
|
||||
'favicon' => null
|
||||
];
|
||||
$ch = curl_init($url);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
$html = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
|
||||
if ($html === false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$meta = @get_meta_tags( $url );
|
||||
|
||||
$dom = new \DOMDocument('1.0', 'utf-8');
|
||||
$dom->strictErrorChecking = false;
|
||||
$dom->loadHTML($html, LIBXML_NOERROR);
|
||||
$xml = simplexml_import_dom($dom);
|
||||
$arr = $xml->xpath('//link[@rel="shortcut icon"]');
|
||||
|
||||
// Get the title of the page
|
||||
$titles = $dom->getElementsByTagName('title');
|
||||
if ($titles->length > 0) {
|
||||
$metaInfo['title'] = $titles->item(0)->nodeValue;
|
||||
}
|
||||
|
||||
// Get the meta tags
|
||||
$metaTags = $dom->getElementsByTagName('meta');
|
||||
$metadata = [];
|
||||
foreach ($metaTags as $meta) {
|
||||
$metadata[] = [
|
||||
'name' => $meta->getAttribute('name'),
|
||||
'property' => $meta->getAttribute('property'),
|
||||
'content' => $meta->getAttribute('content')
|
||||
];
|
||||
if ($meta->getAttribute('name') === 'description') {
|
||||
$metaInfo['description'] = $meta->getAttribute('content');
|
||||
}
|
||||
if ($meta->getAttribute('itemprop') === 'image') {
|
||||
$metaInfo['google_image'] = $meta->getAttribute('content');
|
||||
}
|
||||
if ($meta->getAttribute('property') === 'og:image') {
|
||||
$metaInfo['image'] = $meta->getAttribute('content');
|
||||
}
|
||||
}
|
||||
|
||||
// Get the link tags to find the favicon
|
||||
$linkTags = $dom->getElementsByTagName('link');
|
||||
$metadata['links'] = [];
|
||||
foreach ($linkTags as $link) {
|
||||
$metadata['links'][] = [ $link->getAttribute('rel') => $link->getAttribute('href') ];
|
||||
if ( $link->getAttribute('rel') === 'icon' || $link->getAttribute('rel') === 'shortcut icon') {
|
||||
$metaInfo['favicon'] = $link->getAttribute('href');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$metaInfo['metadata'] = $metadata;
|
||||
|
||||
return $metaInfo;
|
||||
}
|
||||
|
||||
public function retrieveInfo( $url ) {
|
||||
$finalDestination = $this->resolveShortenedUrl( $url );
|
||||
$info = $this->getMetaTagsAndFavicon( $finalDestination );
|
||||
$base_url = $this->getBaseUrl( $finalDestination );
|
||||
|
||||
if ( ! empty( $info['favicon'] ) ) {
|
||||
echo 'favicon exists' . PHP_EOL;
|
||||
if ( stripos( $info['favicon'], 'http' ) !== false) {
|
||||
echo 'favicon is full url' . PHP_EOL;
|
||||
$imageUrl = $info['favicon'];
|
||||
} else {
|
||||
echo 'favicon is not full url' . PHP_EOL;
|
||||
$imageUrl = trim( $base_url, '/' ) . '/' . ltrim( $info['favicon'], '/' );
|
||||
}
|
||||
if ( $this->isValidImageUrl( $imageUrl ) ) {
|
||||
echo 'image is valid' . PHP_EOL;
|
||||
$info['favicon'] = $imageUrl;
|
||||
} else {
|
||||
echo 'image is not valid' . PHP_EOL;
|
||||
$base_info = $this->getMetaTagsAndFavicon( $base_url );
|
||||
if ( ! empty( $base_info['favicon'] ) ) {
|
||||
echo 'parent favicon exists!';
|
||||
if ( stripos( $base_info['favicon'], 'http' ) !== false) {
|
||||
echo 'parent favicon is full url' . PHP_EOL;
|
||||
$imageUrl = $base_info['favicon'];
|
||||
} else {
|
||||
echo 'parent favicon is not full url' . PHP_EOL;
|
||||
$imageUrl = trim( $base_url, '/' ) . '/' . ltrim( $base_info['favicon'], '/' );
|
||||
}
|
||||
if ( $this->isValidImageUrl( $imageUrl ) ) {
|
||||
echo 'parent favicon image is valid' . PHP_EOL;
|
||||
$info['favicon'] = $imageUrl;
|
||||
} else {
|
||||
echo 'parent favicon image is not valid' . PHP_EOL;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
echo 'favicon does not exist' . PHP_EOL;
|
||||
$base_info = $this->getMetaTagsAndFavicon( $base_url );
|
||||
if ( ! empty( $base_info['favicon'] ) ) {
|
||||
echo 'parent favicon exists!' . PHP_EOL;
|
||||
if ( stripos( $base_info['favicon'], 'http' ) !== false) {
|
||||
echo 'parent favicon is full url' . PHP_EOL;
|
||||
$imageUrl = $base_info['favicon'];
|
||||
} else {
|
||||
echo 'parent favicon is not full url' . PHP_EOL;
|
||||
$imageUrl = trim( $base_url, '/' ) . '/' . ltrim( $base_info['favicon'], '/' );
|
||||
}
|
||||
if ( $this->isValidImageUrl( $imageUrl ) ) {
|
||||
echo 'parent favicon image is valid' . PHP_EOL;
|
||||
$info['favicon'] = $imageUrl;
|
||||
} else {
|
||||
echo 'parent favicon image is not valid' . PHP_EOL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
public function refreshInfo( $id ) {
|
||||
if ( !Check::id( $id ) ) {
|
||||
Debug::info( 'Bookmarks: illegal ID.' );
|
||||
return false;
|
||||
}
|
||||
$bookmark = self::findById( $id );
|
||||
if ( $bookmark == false ) {
|
||||
Debug::info( 'Bookmarks not found.' );
|
||||
return false;
|
||||
}
|
||||
if ( $bookmark->createdBy != App::$activeUser->ID ) {
|
||||
Debug::info( 'You do not have permission to modify this bookmark.' );
|
||||
return false;
|
||||
}
|
||||
if ( time() < ( $bookmark->refreshedAt + ( 60 * 10 ) ) ) {
|
||||
Debug::info( 'You may only fetch bookmarks once every 10 minutes.' );
|
||||
return false;
|
||||
}
|
||||
|
||||
$info = $this->retrieveInfo( $bookmark->url );
|
||||
|
||||
$fields = [
|
||||
// 'refreshedAt' => time(),
|
||||
];
|
||||
|
||||
if ( empty( $bookmark->title ) && ! empty( $info['title'] ) ) {
|
||||
$fields['title'] = $info['title'];
|
||||
}
|
||||
if ( empty( $bookmark->description ) && ! empty( $info['description'] ) ) {
|
||||
$fields['description'] = $info['description'];
|
||||
}
|
||||
|
||||
if ( ( empty( $bookmark->icon ) || ! $this->isValidImageUrl( $bookmark->icon ) ) && ! empty( $info['favicon'] ) ) {
|
||||
$fields['icon'] = $info['favicon'];
|
||||
}
|
||||
$fields['meta'] = json_encode( $info['metadata'] );
|
||||
|
||||
if ( !self::$db->update( $this->tableName, $id, $fields ) ) {
|
||||
new CustomException( 'bookmarkUpdate' );
|
||||
Debug::error( "Bookmarks: $id not updated" );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private function getBaseUrl ($url ) {
|
||||
$parsedUrl = parse_url($url);
|
||||
|
||||
if (isset($parsedUrl['scheme']) && isset($parsedUrl['host'])) {
|
||||
return $parsedUrl['scheme'] . '://' . $parsedUrl['host'] . '/';
|
||||
} else {
|
||||
return null; // URL is not valid or cannot be parsed
|
||||
}
|
||||
}
|
||||
|
||||
function isValidImageUrl($url) {
|
||||
$headers = @get_headers($url);
|
||||
if ($headers && strpos($headers[0], '200') !== false) {
|
||||
|
||||
return true;
|
||||
// Further check to ensure it's an image
|
||||
foreach ($headers as $header) {
|
||||
if (strpos(strtolower($header), 'content-type:') !== false) {
|
||||
if (strpos(strtolower($header), 'image/') !== false) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user