Skip to content

Commit

Permalink
Ticket #4695 - Embeds improvements.
Browse files Browse the repository at this point in the history
  • Loading branch information
AntonLV committed Apr 22, 2024
1 parent 44897f8 commit b61b0c3
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 127 deletions.
27 changes: 13 additions & 14 deletions inc/classes/BxDolEmbed.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@
*
* Create an embed from a link.
*
* @section editor_create Creating the Editor object:
* @section embed_provider_create Creating the Editor object:
*
*
* Add record to 'sys_objects_embeds' table:
*
* - object: name of the embed object, in the format: vendor prefix, underscore, module prefix, underscore, internal identifier or nothing
* - title: title of the embed provider, dmay be isplayed in the Studio.
* - override_class_name: user defined class name which is derived from one of base editor classes.
* - override_class_name: user defined class name which is derived from one of base embed provider classes.
* - override_class_file: the location of the user defined class, leave it empty if class is located in system folders.
*
*
Expand All @@ -29,7 +29,7 @@
*
* @code
* $oEmbed = BxDolEmbed::getObjectInstance(); // get default embed object instance
* if ($oEmbed) // check if editor is available for using
* if ($oEmbed) // check if embed provider is available for using
* echo $oEmbed->getLinkHTML ('https://una.io', 'UNA.IO'); // output HTML which will be automatically converted into embed upon page load
* else
* echo '<a href="https://una.io">UNA.IO</a>';
Expand All @@ -41,7 +41,7 @@ class BxDolEmbed extends BxDolFactoryObject
protected $_bCssJsAdded = false;
protected $_sTableName = '';
/**
* Get editor object instance by object name
* Get embed provider object instance by object name
* @param $sObject object name
* @return object instance or false on error
*/
Expand All @@ -61,33 +61,32 @@ static public function getObjectInstance($sObject = false, $oTemplate = false)
*/
public function getLinkHTML ($sLink, $sTitle = '', $sMaxWidth = '')
{
// override this function in particular editor class
// override this function in particular embed provider class
}

/**
* Add css/js files which are needed for embed display and functionality.
*/
public function addJsCss ()
{
// override this function in particular editor class
// override this function in particular embed provider class
}

public function getData ($sUrl, $sTheme)
{
$sData = BxDolEmbedQuery::getLocal($sUrl, $sTheme, $this->_sTableName);
if (!$sData){
if(!$sData) {
$sData = $this->getDataFromApi($sUrl, $sTheme);
if ($sData){
if($sData)
BxDolEmbedQuery::setLocal($sUrl, $sTheme, $this->_sTableName, $sData);
}
}
$aData = json_decode($sData, true);
return $aData;

return json_decode($sData, true);
}
public function getHtml ($sUrl, $sTheme)

public function getDataFromApi ($sUrl, $sTheme)
{
// override this function in particular editor class
// override this function in particular embed provider class
}
}

Expand Down
26 changes: 14 additions & 12 deletions inc/utils.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -2163,29 +2163,31 @@ function bx_linkify($text, $sAttrs = '', $bHtmlSpecialChars = false)
return $text;
}

function bx_linkify_embeded($text)
function bx_linkify_embeded($sText)
{
$urlRegex = '/\b((https?:\/\/)|(www\.))((([0-9a-zA-Z_!~*\'().&=+$%-]+:)?[0-9a-zA-Z_!~*\'().&=+$%-]+@)?(([0-9]{1,3}\.){3}[0-9]{1,3}|([0-9a-zA-Z_!~*\'()-]+\.)*([0-9a-zA-Z][0-9a-zA-Z-]{0,61})?[0-9a-zA-Z]\.[a-zA-Z]{2,16})(:[0-9]{1,4})?((\/[0-9a-zA-Z_!~*\'().;?:@&=+$,%#-]*)*))/';
preg_match_all($urlRegex, $text, $matches, PREG_SET_ORDER);
$sRegex = '/\b((https?:\/\/)|(www\.))((([0-9a-zA-Z_!~*\'().&=+$%-]+:)?[0-9a-zA-Z_!~*\'().&=+$%-]+@)?(([0-9]{1,3}\.){3}[0-9]{1,3}|([0-9a-zA-Z_!~*\'()-]+\.)*([0-9a-zA-Z][0-9a-zA-Z-]{0,61})?[0-9a-zA-Z]\.[a-zA-Z]{2,16})(:[0-9]{1,4})?((\/[0-9a-zA-Z_!~*\'().;?:@&=+$,%#-]*)*))/';
$aMatches = [];
preg_match_all($sRegex, $sText, $aMatches, PREG_SET_ORDER);

// Reverse the matches to mimic JavaScript's reverse order processing
$matches = array_reverse($matches);
$aMatches = array_reverse($aMatches);

$sLink = '';
foreach ($matches as $match) {
foreach ($aMatches as $match) {
// Assuming APP_URL and UNA_URL are defined constants
if (!strstr($match[0], 'https://ci.una.io/') && !strstr($match[0], 'https://ci.una.io/')) {
$sLink = $match[0]; // Returns the first URL that doesn't include the restricted domains
}
}
$text = '';
if ($sLink){

$sResult = '';
if($sLink) {
bx_import('BxDolEmbed');
$oEmbed = BxDolEmbed::getObjectInstance('sys_system');
$text = $oEmbed->getHtml($sLink, '');
if(($oEmbed = BxDolEmbed::getObjectInstance('sys_system')) !== false)
$sResult = $oEmbed->getLinkHTML($sLink);
}
return $text;

return $sResult;
}

/**
Expand Down
30 changes: 7 additions & 23 deletions oembed.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,11 @@
require_once(BX_DIRECTORY_PATH_INC . "design.inc.php");

$aLinks = bx_get('l');
bx_import('BxDolEmbed');
$oEmbed = BxDolEmbed::getObjectInstance('sys_system');
/*
echo bx_file_get_contents('https://publish.twitter.com/oembed?url=https://twitter.com/callmehouck/status/1780211820424569127', [], 'get', ['Accept: text/html'], $iHttpCode, [], 0, [CURLOPT_USERAGENT => false]);*/


//, bx_get('theme')
if (bx_get('html')){
/* $a = bx_get_site_info($aLinks, array(
'thumbnailUrl' => array('tag' => 'link', 'content_attr' => 'href'),
'OGImage' => array('name_attr' => 'property', 'name' => 'og:image'),
'icon' => array('tag' => 'link', 'name_attr' => 'rel', 'name' => 'shortcut icon', 'content_attr' => 'href'),
'icon2' => array('tag' => 'link', 'name_attr' => 'rel', 'name' => 'icon', 'content_attr' => 'href'),
'icon3' => array('tag' => 'link', 'name_attr' => 'rel', 'name' => 'apple-touch-icon', 'content_attr' => 'href'),
));
print_r( $a);*/
echo '<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;"" /><style>body, html {margin:0px} A{text-decoration:none; color:#222}</style><div style=" margin:0px auto; justify-content: center;" id="ifr">
'.$oEmbed->getHtml($aLinks, '');
exit();
}
echoJson($oEmbed->parseLinks($aLinks));
bx_import('BxDolEmbed');
if(($oEmbed = BxDolEmbed::getObjectInstance('sys_system')) !== false) {
if(bx_get('html'))
echo '<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;"" /><style>body, html {margin:0px} A{text-decoration:none; color:#222}</style><div style=" margin:0px auto; justify-content: center;" id="ifr">' . $oEmbed->getLinkHTML($aLinks) . '</div>';
else
echoJson($oEmbed->parseLinks($aLinks));
}
13 changes: 13 additions & 0 deletions template/embed_system_link.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<a href="__link__" target="_blank" style="text-decoration: none; color: inherit;" __attrs__>
<div style="display: flex; flex-direction: row; column-gap: height: 128px; border: 1px solid rgba(107, 114, 128, 0.2); border-radius:16px; align-items: stretch;">
<div style="flex: 0 0 128px; height: 128px; border-radius:16px 0 0 16px; background: url('__image__') center center / cover no-repeat;">
</div>
<div style="flex-grow: 1; display: flex; flex-direction: column; justify-content: space-between; overflow: hidden;margin: 0 1rem">
<div style="padding-top: 0.5rem; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 1; overflow: hidden; text-overflow: ellipsis"><b>__title__</b></div>
<div style="display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; text-overflow: ellipsis;">__description__</div>
<div style="display: flex; flex-direction: row; column-gap: 8px; align-items: center; padding-bottom: 0.5rem;">
<img src="__logo__" width=24 height=24 >__domain__
</div>
</div>
</div>
</a>
119 changes: 41 additions & 78 deletions template/scripts/BxBaseEmbedSystem.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
*/

/**
* Iframely integration.
* System (default) integration.
*
* @see BxDolEmbed
*/
class BxBaseEmbedSystem extends BxDolEmbed
Expand All @@ -26,9 +27,11 @@ public function __construct ($aObject, $oTemplate)

public function getLinkHTML ($sLink, $sTitle = '', $sMaxWidth = '')
{
$aAttrs = array(
$aData = $this->getData($sLink, '');

$aAttrs = [
'title' => bx_html_attribute($sTitle),
);
];

// check for external link
if (strncmp(BX_DOL_URL_ROOT, $sLink, strlen(BX_DOL_URL_ROOT)) !== 0) {
Expand All @@ -38,58 +41,43 @@ public function getLinkHTML ($sLink, $sTitle = '', $sMaxWidth = '')
$aAttrs['rel'] = 'nofollow';
}

return $this->_oTemplate->parseHtmlByName('embed_iframely_link.html', array(
'link' => $sLink,
'title' => $sTitle,
return $this->_oTemplate->parseHtmlByName('embed_system_link.html', [
'link' => $aData['url'],
'attrs' => bx_convert_array2attrs($aAttrs),
'width' => $sMaxWidth,
));
}

public function addProcessLinkMethod ()
{
return "
<script>
function bx_embed_link(e)
{
window.iframely && iframely.load(e);
}
</script>";
'image' => $aData['image'] ? $aData['image'] : $aData['logo'],
'logo' => $aData['logo'],
'title' => $aData['title'],
'description' => $aData['description'],
'domain' => $aData['domain'],
]);
}



public function getDataFromApi ($sUrl, $sTheme)
{
$a = bx_get_site_info($sUrl, array(
'thumbnailUrl' => array('tag' => 'link', 'content_attr' => 'href'),
'OGImage' => array('name_attr' => 'property', 'name' => 'og:image'),
'icon' => array('tag' => 'link', 'name_attr' => 'rel', 'name' => 'shortcut icon', 'content_attr' => 'href'),
'icon2' => array('tag' => 'link', 'name_attr' => 'rel', 'name' => 'icon', 'content_attr' => 'href'),
'icon3' => array('tag' => 'link', 'name_attr' => 'rel', 'name' => 'apple-touch-icon', 'content_attr' => 'href'),
));
$a = bx_get_site_info($sUrl, [
'thumbnailUrl' => ['tag' => 'link', 'content_attr' => 'href'],
'OGImage' => ['name_attr' => 'property', 'name' => 'og:image'],
'icon' => ['tag' => 'link', 'name_attr' => 'rel', 'name' => 'shortcut icon', 'content_attr' => 'href'],
'icon2' => ['tag' => 'link', 'name_attr' => 'rel', 'name' => 'icon', 'content_attr' => 'href'],
'icon3' => ['tag' => 'link', 'name_attr' => 'rel', 'name' => 'apple-touch-icon', 'content_attr' => 'href'],
]);

$a['image'] = $a['OGImage'] ? $a['OGImage'] : $a['thumbnailUrl'];
$a['logo'] = $a['icon2'] ? $a['icon2'] : ($a['icon3'] ? $a['icon3'] : $a['icon']);
$a['url'] = $sUrl;
$a = array_merge($a, [
'image' => $a['OGImage'] ? $a['OGImage'] : $a['thumbnailUrl'],
'logo' => $a['icon2'] ? $a['icon2'] : ($a['icon3'] ? $a['icon3'] : $a['icon']),
'url' => $sUrl
]);

unset($a['OGImage'], $a['thumbnailUrl'], $a['icon'], $a['icon2'], $a['icon3']);

unset($a['OGImage']);
unset($a['thumbnailUrl']);
unset($a['icon2']);
unset($a['icon3']);
unset($a['icon']);

if ($a['image']){
$oStorage = BxDolStorage::getObjectInstance('sys_images');

if($a['image'] && ($oStorage = BxDolStorage::getObjectInstance('sys_images')) !== false) {
$iMediaId = $oStorage->storeFileFromUrl($a['image'], false);
if ($iMediaId){
$a['image'] = $oStorage->getFileUrlById($iMediaId);
}
if($iMediaId)
$a['image'] = $oStorage->getFileUrlById($iMediaId);
}
if ($a['image'] == ''){

if($a['image'] == '') {
$b = json_decode(bx_file_get_contents("https://api.microlink.io/?url=" . $sUrl), true);
$a = [
'title' => $b['data']['title'],
Expand All @@ -99,43 +87,18 @@ public function getDataFromApi ($sUrl, $sTheme)
'url' => $sUrl,
];
}

$aU = parse_url($sUrl);
$a['domain'] = $aU['host'];

$aUrl = parse_url($sUrl);
$a['domain'] = $aUrl['host'];

return json_encode($a);
}

public function getDataHtml ($sUrl, $sTheme)
{
$aData = $this->getData($sUrl, $sTheme);
return $aData;
}

public function getHtml ($sUrl, $sTheme)

public function parseLinks(&$aLinks)
{
$aData = $this->getData($sUrl, $sTheme);

return '<a href="'.$aData['url'].'" target="_blank" style="text-decoration: none; color: inherit;">
<div style="display: flex; flex-direction: row; column-gap: height: 128px; border: 1px solid rgba(107, 114, 128, 0.2); border-radius:16px; align-items: stretch;">
<div style="flex: 0 0 128px; height: 128px; border-radius:16px 0 0 16px; background: url('. ($aData['image'] ? $aData['image'] : $aData['logo']) .') center center / cover no-repeat;">
</div>
<div style="flex-grow: 1; display: flex; flex-direction: column; justify-content: space-between; overflow: hidden;margin: 0 1rem">
<div style="padding-top: 0.5rem; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 1; overflow: hidden; text-overflow: ellipsis"><b> '.$aData['title'].'</b></div>
<div style="display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; text-overflow: ellipsis;">
'.$aData['description'].'
</div>
<div style="display: flex; flex-direction: row; column-gap: 8px; align-items: center; padding-bottom: 0.5rem;">
<img src="'.$aData['logo'].'" width=24 height=24 >'.$aData['domain'].'
</div>
</div>
</div>
</a>';

}

public function parseLinks(&$aLinks) {
$aResult = [];
if ($aLinks && is_array($aLinks)) {

if($aLinks && is_array($aLinks)) {
$oEmbera = $this->getEmberaInstance();

foreach ($aLinks as $sLink) {
Expand All @@ -144,9 +107,9 @@ public function parseLinks(&$aLinks) {
$aResult[] = ['html' => $sHtml != $sLink ? $sHtml : ''];
}
}

return $aResult;
}

}

/** @} */

0 comments on commit b61b0c3

Please sign in to comment.