فهرست منبع

Merge branch 'master' of https://github.com/boonex/dolphin

AntonLV 10 سال پیش
والد
کامیت
1b8ea6e79e
25فایلهای تغییر یافته به همراه543 افزوده شده و 10 حذف شده
  1. 1 1
      inc/classes/BxDolCmts.php
  2. 16 8
      inc/utils.inc.php
  3. 27 0
      modules/boonex/datafox/classes/BxDataFoxAlertsResponse.php
  4. 22 0
      modules/boonex/datafox/classes/BxDataFoxConfig.php
  5. 20 0
      modules/boonex/datafox/classes/BxDataFoxDb.php
  6. 145 0
      modules/boonex/datafox/classes/BxDataFoxModule.php
  7. 28 0
      modules/boonex/datafox/classes/BxDataFoxStudioPage.php
  8. 20 0
      modules/boonex/datafox/classes/BxDataFoxTemplate.php
  9. 68 0
      modules/boonex/datafox/install/config.php
  10. 20 0
      modules/boonex/datafox/install/installer.php
  11. 7 0
      modules/boonex/datafox/install/langs/en.xml
  12. 15 0
      modules/boonex/datafox/install/sql/disable.sql
  13. 30 0
      modules/boonex/datafox/install/sql/enable.sql
  14. 14 0
      modules/boonex/datafox/install/sql/install.sql
  15. 7 0
      modules/boonex/datafox/install/sql/uninstall.sql
  16. 18 0
      modules/boonex/datafox/request.php
  17. 19 0
      modules/boonex/datafox/template/companies.html
  18. 24 0
      modules/boonex/datafox/template/css/datafox.css
  19. BIN
      modules/boonex/datafox/template/images/icons/std-mi.png
  20. BIN
      modules/boonex/datafox/template/images/icons/std-pi.png
  21. BIN
      modules/boonex/datafox/template/images/icons/std-si.png
  22. BIN
      modules/boonex/datafox/template/images/icons/std-wi.png
  23. 1 1
      modules/boonex/timeline/classes/BxTimelineTemplate.php
  24. 36 0
      plugins/htmlpurifier/standalone/HTMLPurifier/Filter/AddBxLinksClass.php
  25. 5 0
      template/css/editor.css

+ 1 - 1
inc/classes/BxDolCmts.php

@@ -910,7 +910,7 @@ class BxDolCmts extends BxDol implements iBxDolReplaceable
     {
     	$iDataAction = $this->isNl2br() ? BX_DATA_TEXT_MULTILINE : BX_DATA_HTML;
     	$s = bx_process_output($s, $iDataAction);
-    	$s = bx_linkify_html($s);
+    	$s = bx_linkify_html($s, 'class="' . BX_DOL_LINK_CLASS . '"');
 
         if ($this->_sMetatagsObj && $iCmtId) {
             $oMetatags = BxDolMetatags::getObjectInstance($this->_sMetatagsObj);

+ 16 - 8
inc/utils.inc.php

@@ -7,6 +7,8 @@
  * @{
  */
 
+define('BX_DOL_LINK_CLASS', 'bx-link'); ///< class to add to every link in user content
+
 define('BX_DATA_TEXT', 1); ///< regular text data type
 define('BX_DATA_TEXT_MULTILINE', 2); ///< regular multiline text data type
 define('BX_DATA_INT', 3); ///< integer data type
@@ -449,13 +451,11 @@ function echoJson($a)
 
 function clear_xss($val)
 {
-    if ($GLOBALS['logged']['admin'])
-        return $val;
-
     // HTML Purifier plugin
     global $oHtmlPurifier;
-    require_once( BX_DIRECTORY_PATH_PLUGINS . 'htmlpurifier/HTMLPurifier.standalone.php' );
-    if (!isset($oHtmlPurifier)) {
+    if (!isset($oHtmlPurifier) && !$GLOBALS['logged']['admin']) {
+
+        require_once( BX_DIRECTORY_PATH_PLUGINS . 'htmlpurifier/HTMLPurifier.standalone.php' );
 
         HTMLPurifier_Bootstrap::registerAutoload();
 
@@ -474,7 +474,7 @@ function clear_xss($val)
             $oConfig->set('HTML.Nofollow', 'true');
         }
 
-        $oConfig->set('Filter.Custom', array (new HTMLPurifier_Filter_YouTube(), new HTMLPurifier_Filter_YoutubeIframe()));
+        $oConfig->set('Filter.Custom', array (new HTMLPurifier_Filter_YouTube(), new HTMLPurifier_Filter_YoutubeIframe(), new HTMLPurifier_Filter_AddBxLinksClass()));
 
         $oDef = $oConfig->getHTMLDefinition(true);
         $oDef->addAttribute('a', 'target', 'Enum#_blank,_self,_target,_top');
@@ -482,7 +482,12 @@ function clear_xss($val)
         $oHtmlPurifier = new HTMLPurifier($oConfig);
     }
 
-    return $oHtmlPurifier->purify($val);
+    if (!$GLOBALS['logged']['admin'])
+        $val = $oHtmlPurifier->purify($val);
+
+    bx_alert('system', 'clear_xss', 0, 0, array('oHtmlPurifier' => $oHtmlPurifier, 'return_data' => &$val));
+
+    return $val;
 }
 
 //--------------------------------------- friendly permalinks --------------------------------------//
@@ -739,7 +744,7 @@ function bx_php_string_quot ($mixedInput)
  * @param array $aHeaders - custom headers.
  * @return string the file's contents.
  */
-function bx_file_get_contents($sFileUrl, $aParams = array(), $sMethod = 'get', $aHeaders = array(), &$sHttpCode = null)
+function bx_file_get_contents($sFileUrl, $aParams = array(), $sMethod = 'get', $aHeaders = array(), &$sHttpCode = null, $aBasicAuth = array())
 {
     $bChangeTimeout = false;
 
@@ -766,6 +771,9 @@ function bx_file_get_contents($sFileUrl, $aParams = array(), $sMethod = 'get', $
         if ($aHeaders)
             curl_setopt($rConnect, CURLOPT_HTTPHEADER, $aHeaders);
 
+        if ($aBasicAuth)
+            curl_setopt($rConnect, CURLOPT_USERPWD, $aBasicAuth['user'] . ':' . $aBasicAuth['password']);
+
         if ('post' == $sMethod) {
             curl_setopt($rConnect, CURLOPT_POST, true);
             curl_setopt($rConnect, CURLOPT_POSTFIELDS, $aParams);

+ 27 - 0
modules/boonex/datafox/classes/BxDataFoxAlertsResponse.php

@@ -0,0 +1,27 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * CC-BY License - http://creativecommons.org/licenses/by/3.0/
+ *
+ * @defgroup    DataFox Data Fox API integration
+ * @ingroup     TridentModules
+ *
+ * @{
+ */
+
+/**
+ * alerts handler
+ */
+class BxDataFoxAlertsResponse extends BxDolAlertsResponse
+{
+    public function response($oAlert)
+    {
+        if ('system' != $oAlert->sUnit || 'clear_xss' != $oAlert->sAction || !getParam('bx_datafox_id'))
+            return;
+
+        $a = $oAlert->aExtras;
+        $a['return_data'] = BxDolService::call('bx_datafox', 'parse_text', array($a['return_data']));
+    }
+}
+
+/** @} */

+ 22 - 0
modules/boonex/datafox/classes/BxDataFoxConfig.php

@@ -0,0 +1,22 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * CC-BY License - http://creativecommons.org/licenses/by/3.0/
+ *
+ * @defgroup    DataFox Data Fox API integration
+ * @ingroup     TridentModules
+ *
+ * @{
+ */
+
+class BxDataFoxConfig extends BxDolModuleConfig
+{
+    public $sApiUrl = 'https://api.datafox.co/1.0/';
+
+    function __construct($aModule)
+    {
+        parent::__construct($aModule);
+    }
+}
+
+/** @} */

+ 20 - 0
modules/boonex/datafox/classes/BxDataFoxDb.php

@@ -0,0 +1,20 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * CC-BY License - http://creativecommons.org/licenses/by/3.0/
+ *
+ * @defgroup    DataFox Data Fox API integration
+ * @ingroup     TridentModules
+ *
+ * @{
+ */
+
+class BxDataFoxDb extends BxDolModuleDb
+{
+    function __construct(&$oConfig)
+    {
+        parent::__construct($oConfig);
+    }
+}
+
+/** @} */

+ 145 - 0
modules/boonex/datafox/classes/BxDataFoxModule.php

@@ -0,0 +1,145 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * CC-BY License - http://creativecommons.org/licenses/by/3.0/
+ *
+ * @defgroup    DataFox Data Fox API integration
+ * @ingroup     TridentModules
+ *
+ * @{
+ */
+
+class BxDataFoxModule extends BxDolModule
+{
+    function __construct(&$aModule)
+    {
+        parent::__construct($aModule);
+    }
+
+    function serviceIncludeCssJs()
+    {
+        $this->_oTemplate->addCss('datafox.css');
+    }
+
+    function serviceParseText($sHtml)
+    {
+        if (false === strstr($sHtml, '<a '))
+            return $sHtml;
+        
+        $sId = 'bx-datafox-' . md5(microtime());
+
+        // load html with wrapper
+        $dom = new DOMDocument();
+        @$dom->loadHTML('<?xml encoding="UTF-8"><div id="' . $sId . '">' . $sHtml . '</div>');
+        $xpath = new DOMXpath($dom);
+
+        // grab links, also add special classes
+        $aLinks = array();
+        $oLinks = $xpath->evaluate('//a');
+        for ($i = 0; $i < $oLinks->length; $i++) {
+            $oLink = $oLinks->item($i);
+            $sIdLink = $sId . '_' . $i;
+
+            $aLinks[$sIdLink] = $oLink->getAttribute('href');
+
+            $sClasses = $oLink->getAttribute('class');
+            $sClasses = ($sClasses ? preg_replace('/\s*bx-datafox-[a-zA-Z0-9]+_[0-9]+/', '', $sClasses) . ' ' : '') . $sIdLink;
+
+            $oLink->removeAttribute('class');
+            $oLink->setAttribute("class", $sClasses);
+        }
+
+        // remove old code with references
+        $eCont = $dom->getElementById($sId);
+        foreach ($xpath->query('//div[contains(attribute::class, "bx-datafox-companies")]', $eCont) as $e)
+            $e->parentNode->removeChild($e);
+
+        // save the result 
+        if (false === ($s = $dom->saveXML($dom->getElementById($sId)))) // in case of error return original string
+            return $sHtml;
+
+        // strip added tags
+        $sHtml = mb_substr($s, 54, -6); 
+
+        // add new code with references
+        $aCompanies = $this->apiGetCompanies($aLinks);
+
+        $sHtml .= $this->_oTemplate->parseHtmlByName('companies.html', array(
+            'bx_repeat:companies' => $aCompanies,
+        ));
+
+        return $sHtml;
+    }
+
+    function apiGetCompanies($aLinks)
+    {
+        $sAccessToken = $this->apiGetAccessToken();
+        $aCompanies = array();
+        $iCounter = 0;
+        foreach ($aLinks as $sId => &$sHref) {
+            if (!($a = $this->apiGetCompanyByUrl($sAccessToken, $sHref, $aCompanies)))
+                continue;
+            $a['link_id'] = $sId;
+            $a['item_number'] = ++$iCounter;
+            unset($a['top_keywords']);
+            $aCompanies[$a['id']] = $a;
+        }
+        return $aCompanies;
+    }
+
+    function apiGetAccessToken()
+    {
+        // make request for token
+        $sHttpCode = null;
+        $s = bx_file_get_contents($this->_oConfig->sApiUrl . 'oauth2/token', array(
+            'grant_type' => 'client_credentials',
+            'scope' => 'full',
+        ), 'post', array(), $sHttpCode, array(
+            'user' => getParam('bx_datafox_id'), 
+            'password' => getParam('bx_datafox_secret'),
+        ));
+
+        if (!$s)
+            return false;
+
+        $o = json_decode($s);
+
+        return $o && isset($o->access_token) ? $o->access_token : '';
+    }
+
+    function apiGetCompanyByUrl($sAccessToken, $sHref, $aCompanies)
+    {
+        $sHost = parse_url($sHref, PHP_URL_HOST);
+        if (!$sHref)
+            return false;
+
+        $a = $this->api($sAccessToken, 'companies', array('url' => $sHost));
+
+        if (!isset($a['total_count']) || !$a['total_count'] && $a['entries'])
+            return false;
+
+        $aCompany = array_pop($a['entries']);
+
+        if (isset($aCompanies[$aCompany['id']]))
+            return false;
+
+        $aCompanyFull = $this->api($sAccessToken, 'companies/' . $aCompany['id'] . '/details');
+
+        return $aCompanyFull;
+    }
+
+    function api($sAccessToken, $sUrlAppend, $aData = array())
+    {
+        $s = bx_file_get_contents($this->_oConfig->sApiUrl . $sUrlAppend, $aData, 'get', array(
+            'Authorization: Bearer ' . $sAccessToken,
+        ));
+
+        if (!$s || !($a = json_decode($s, true)) || (isset($a['object_type']) && 'error' == $a['object_type']))
+            return false;
+
+        return $a;
+    }
+
+}
+
+/** @} */

+ 28 - 0
modules/boonex/datafox/classes/BxDataFoxStudioPage.php

@@ -0,0 +1,28 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * CC-BY License - http://creativecommons.org/licenses/by/3.0/
+ *
+ * @defgroup    DataFox Data Fox API integration
+ * @ingroup     TridentModules
+ *
+ * @{
+ */
+
+class BxDataFoxStudioPage extends BxTemplStudioModule
+{
+    protected $oModule;
+
+    function __construct($sModule = "", $sPage = "")
+    {
+        parent::__construct($sModule, $sPage);
+
+        $this->oModule = BxDolModule::getInstance('bx_datafox');
+
+        $this->aMenuItems = array(
+            array('name' => 'general', 'icon' => 'cogs', 'title' => '_adm_lmi_cpt_settings'),
+        );
+    }
+}
+
+/** @} */

+ 20 - 0
modules/boonex/datafox/classes/BxDataFoxTemplate.php

@@ -0,0 +1,20 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * CC-BY License - http://creativecommons.org/licenses/by/3.0/
+ *
+ * @defgroup    DataFox Data Fox API integration
+ * @ingroup     TridentModules
+ *
+ * @{
+ */
+
+class BxDataFoxTemplate extends BxDolModuleTemplate
+{
+    function __construct(&$oConfig, &$oDb)
+    {
+        parent::__construct($oConfig, $oDb);
+    }
+}
+
+/** @} */

+ 68 - 0
modules/boonex/datafox/install/config.php

@@ -0,0 +1,68 @@
+<?php
+/**
+ * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * CC-BY License - http://creativecommons.org/licenses/by/3.0/
+ *
+ * @defgroup    DataFox Data Fox API integration
+ * @ingroup     TridentModules
+ *
+ * @{
+ */
+
+$aConfig = array(
+    /**
+     * Main Section.
+     */
+    'type' => BX_DOL_MODULE_TYPE_MODULE,
+    'name' => 'bx_datafox',
+    'title' => 'Data Fox',
+    'note' => 'Data Fox API integration.',
+    'version' => '8.0.0.DEV',
+    'vendor' => 'BoonEx',
+	'help_url' => 'http://feed.boonex.com/?section={module_name}',
+
+    'compatible_with' => array(
+        '8.0.x'
+    ),
+
+    /**
+     * 'home_dir' and 'home_uri' - should be unique. Don't use spaces in 'home_uri' and the other special chars.
+     */
+    'home_dir' => 'boonex/datafox/',
+    'home_uri' => 'datafox',
+
+    'db_prefix' => 'bx_datafox_',
+    'class_prefix' => 'BxDataFox',
+
+    /**
+     * Category for language keys.
+     */
+    'language_category' => 'Data Fox',
+
+    /**
+     * Installation/Uninstallation Section.
+     */
+    'install' => array(
+        'execute_sql' => 1,
+        'update_languages' => 1,
+    ),
+    'uninstall' => array (
+        'execute_sql' => 1,
+        'update_languages' => 1,
+    ),
+    'enable' => array(
+        'execute_sql' => 1,
+        'clear_db_cache' => 1,
+    ),
+    'disable' => array(
+        'execute_sql' => 1,
+        'clear_db_cache' => 1,
+    ),
+
+    /**
+     * Dependencies Section
+     */
+    'dependencies' => array(),
+);
+
+/** @} */

+ 20 - 0
modules/boonex/datafox/install/installer.php

@@ -0,0 +1,20 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * CC-BY License - http://creativecommons.org/licenses/by/3.0/
+ *
+ * @defgroup    DataFox Data Fox API integration
+ * @ingroup     TridentModules
+ *
+ * @{
+ */
+
+class BxDataFoxInstaller extends BxDolStudioInstaller
+{
+    function __construct($aConfig)
+    {
+        parent::__construct($aConfig);
+    }
+}
+
+/** @} */

+ 7 - 0
modules/boonex/datafox/install/langs/en.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources name="en" flag="gb" title="English">
+	<string name="_bx_datafox"><![CDATA[Data Fox]]></string>
+    <string name="_bx_datafox_adm_stg_cpt_type"><![CDATA[Data Fox]]></string>
+    <string name="_bx_datafox_adm_stg_cpt_category_general"><![CDATA[General]]></string>
+</resources>
+

+ 15 - 0
modules/boonex/datafox/install/sql/disable.sql

@@ -0,0 +1,15 @@
+
+-- settings
+
+DELETE FROM `top`, `toc`, `to` USING `sys_options_types` AS `top` LEFT JOIN `sys_options_categories` AS `toc` ON `top`.`id`=`toc`.`type_id` LEFT JOIN `sys_options` AS `to` ON `toc`.`id`=`to`.`category_id` WHERE `top`.`name` = 'bx_datafox';
+
+-- alerts
+
+SET @iHandler := (SELECT `id` FROM `sys_alerts_handlers` WHERE `name` = 'bx_datafox' LIMIT 1);
+DELETE FROM `sys_alerts` WHERE `handler_id` = @iHandler;
+DELETE FROM `sys_alerts_handlers` WHERE `id` = @iHandler;
+
+-- injections
+
+DELETE FROM `sys_injections` WHERE `name` = 'bx_datafox';
+

+ 30 - 0
modules/boonex/datafox/install/sql/enable.sql

@@ -0,0 +1,30 @@
+
+-- settings
+
+SET @iTypeOrder = (SELECT MAX(`order`) FROM `sys_options_types` WHERE `group` = 'modules');
+INSERT INTO `sys_options_types` (`group`, `name`, `caption`, `icon`, `order`) VALUES 
+('modules', 'bx_datafox', '_bx_datafox_adm_stg_cpt_type', 'bx_datafox@modules/boonex/datafox/|std-mi.png', IF(NOT ISNULL(@iTypeOrder), @iTypeOrder + 1, 1));
+SET @iTypeId = LAST_INSERT_ID();
+
+INSERT INTO `sys_options_categories` (`type_id`, `name`, `caption`, `order` )  
+VALUES (@iTypeId, 'bx_datafox_general', '_bx_datafox_adm_stg_cpt_category_general', 1);
+SET @iCategId = LAST_INSERT_ID();
+
+INSERT INTO `sys_options` (`name`, `value`, `category_id`, `caption`, `type`, `check`, `check_error`, `order`, `extra`) VALUES
+('bx_datafox_id', '', @iCategId, 'DataFox Client ID', 'digit', '', '', 10, ''),
+('bx_datafox_secret', '', @iCategId, 'DataFox Client Secret', 'digit', '', '', 12, '');
+
+-- alerts
+
+INSERT INTO `sys_alerts_handlers` (`name`, `class`, `file`, `service_call`) VALUES 
+('bx_datafox', 'BxDataFoxAlertsResponse', 'modules/boonex/datafox/classes/BxDataFoxAlertsResponse.php', '');
+SET @iHandler := LAST_INSERT_ID();
+
+INSERT INTO `sys_alerts` (`unit`, `action`, `handler_id`) VALUES
+('system', 'clear_xss', @iHandler);
+
+-- injections
+
+INSERT INTO `sys_injections` (`name`, `page_index`, `key`, `type`, `data`, `replace`, `active`) VALUES
+('bx_datafox', 0, 'injection_head', 'service', 'a:2:{s:6:"module";s:10:"bx_datafox";s:6:"method";s:14:"include_css_js";}', 0, 1);
+

+ 14 - 0
modules/boonex/datafox/install/sql/install.sql

@@ -0,0 +1,14 @@
+
+-- Studio page and widget
+
+INSERT INTO `sys_std_pages`(`index`, `name`, `header`, `caption`, `icon`) VALUES
+(3, 'bx_datafox', '_bx_datafox', '_bx_datafox', 'bx_datafox@modules/boonex/datafox/|std-pi.png');
+SET @iPageId = LAST_INSERT_ID();
+
+SET @iParentPageId = (SELECT `id` FROM `sys_std_pages` WHERE `name` = 'home');
+SET @iParentPageOrder = (SELECT MAX(`order`) FROM `sys_std_pages_widgets` WHERE `page_id` = @iParentPageId);
+INSERT INTO `sys_std_widgets` (`page_id`, `module`, `url`, `click`, `icon`, `caption`, `cnt_notices`, `cnt_actions`) VALUES
+(@iPageId, 'bx_datafox', '{url_studio}module.php?name=bx_datafox', '', 'bx_datafox@modules/boonex/datafox/|std-wi.png', '_bx_datafox', '', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:11:"get_actions";s:6:"params";a:0:{}s:5:"class";s:18:"TemplStudioModules";}');
+INSERT INTO `sys_std_pages_widgets` (`page_id`, `widget_id`, `order`) VALUES
+(@iParentPageId, LAST_INSERT_ID(), IF(ISNULL(@iParentPageOrder), 1, @iParentPageOrder + 1));
+

+ 7 - 0
modules/boonex/datafox/install/sql/uninstall.sql

@@ -0,0 +1,7 @@
+
+-- Studio page and widget
+
+DELETE FROM `tp`, `tw`, `tpw`
+USING `sys_std_pages` AS `tp`, `sys_std_widgets` AS `tw`, `sys_std_pages_widgets` AS `tpw`
+WHERE `tp`.`id` = `tw`.`page_id` AND `tw`.`id` = `tpw`.`widget_id` AND `tp`.`name` = 'bx_datafox';
+

+ 18 - 0
modules/boonex/datafox/request.php

@@ -0,0 +1,18 @@
+<?php
+/**
+ * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * CC-BY License - http://creativecommons.org/licenses/by/3.0/
+ *
+ * @defgroup    SMTPMailer SMTP Mailer
+ * @ingroup     TridentModules
+ *
+ * @{
+ */
+
+require_once(BX_DIRECTORY_PATH_INC . 'profiles.inc.php');
+
+check_logged();
+
+BxDolRequest::processAsAction($GLOBALS['aModule'], $GLOBALS['aRequest']);
+
+/** @} */

+ 19 - 0
modules/boonex/datafox/template/companies.html

@@ -0,0 +1,19 @@
+<div class="bx-datafox-companies bx-hide-in-htmleditor">
+    <hr class="bx-def-hr bx-def-margin-topbottom" />
+    <bx_repeat:companies>
+        <div class="bx-datafox-company bx-def-margin-bottom bx-clearfix" id="__link_id__">
+            <div class="bx-datafox-company-thumb bx-def-round-corners bx-def-border bx-def-margin-sec-right" style="background-image:url(__logo_url__)"></div>
+            <div class="bx-datafox-company-info">
+                <div class="bx-datafox-company-title">__name__</div>
+                <div class="bx-datafox-company-desc bx-def-margin-sec-topbottom">__short_description__</div>
+                <div class="bx-datafox-company-prop"><b>Location:</b> <i>__location__</i></div>
+                <div class="bx-datafox-company-prop"><b>Employees:</b> <i>__number_of_employees__</i></div>
+                <div class="bx-datafox-company-prop"><b>Founded:</b> <i>__founded_year__</i></div>
+    
+            </div>
+        </div>
+        <script>
+            $('<sup><a href="javascript:void(0);" onclick="$(\'html, body\').animate({scrollTop:$(\'#__link_id__\').offset().top}, 500);">[__item_number__]</a></sup>').insertAfter($('a.__link_id__'));
+        </script>
+    </bx_repeat:companies>
+</div>

+ 24 - 0
modules/boonex/datafox/template/css/datafox.css

@@ -0,0 +1,24 @@
+
+.bx-datafox-company {
+    position:relative;
+    float:left;
+}
+
+.bx-datafox-company-thumb {
+    float:left;
+    width:150px;
+    height:150px;
+    background-size:contain;
+    background-position:center center;
+    background-repeat:no-repeat;
+}
+
+.bx-datafox-company-title {
+    font-weight:bold;
+}
+
+.bx-datafox-company-prop b,
+.bx-datafox-company-prop i {
+    font-weight:normal;
+    font-style:normal;
+}

BIN
modules/boonex/datafox/template/images/icons/std-mi.png


BIN
modules/boonex/datafox/template/images/icons/std-pi.png


BIN
modules/boonex/datafox/template/images/icons/std-si.png


BIN
modules/boonex/datafox/template/images/icons/std-wi.png


+ 1 - 1
modules/boonex/timeline/classes/BxTimelineTemplate.php

@@ -960,7 +960,7 @@ class BxTimelineTemplate extends BxBaseModNotificationsTemplate
     protected function _prepareTextForOutput($s, $iEventId = 0)
     {
     	$s = bx_process_output($s, BX_DATA_HTML);
-        $s = bx_linkify_html($s);
+        $s = bx_linkify_html($s, 'class="' . BX_DOL_LINK_CLASS . '"');
 
         $oMetatags = BxDolMetatags::getObjectInstance($this->_oConfig->getObject('metatags'));
 		$s = $oMetatags->keywordsParse($iEventId, $s);

+ 36 - 0
plugins/htmlpurifier/standalone/HTMLPurifier/Filter/AddBxLinksClass.php

@@ -0,0 +1,36 @@
+<?php
+
+class HTMLPurifier_Filter_AddBxLinksClass extends HTMLPurifier_Filter
+{
+    public $name = 'AddBxLinksClass';
+    protected $class = BX_DOL_LINK_CLASS;
+
+    public function preFilter($sHtml, $config, $context)
+    {
+        if (false === strstr($sHtml, '<a '))
+            return $sHtml;
+
+        $sId = 'bx-links-' . md5(microtime());
+        $dom = new DOMDocument();
+        @$dom->loadHTML('<?xml encoding="UTF-8"><div id="' . $sId . '">' . $sHtml . '</div>');
+        $xpath = new DOMXpath($dom);
+
+        $oLinks = $xpath->evaluate('//a');
+        for ($i = 0; $i < $oLinks->length; $i++) {
+            $oLink = $oLinks->item($i);
+
+            $sClasses = $oLink->getAttribute('class');
+            if (!$sClasses || false === strpos($sClasses, $this->class))
+                $sClasses = ($sClasses ? $sClasses . ' ' : '') . $this->class;
+
+            $oLink->removeAttribute('class');
+            $oLink->setAttribute("class", $sClasses);
+        }
+
+        if (false === ($s = $dom->saveXML($dom->getElementById($sId)))) // in case of error return original string
+            return $sHtml;
+
+        return mb_substr($s, 52, -6); // strip added tags
+    }
+}
+

+ 5 - 0
template/css/editor.css

@@ -33,3 +33,8 @@ blockquote {
     border-left: 2px solid #ccc;
     padding-left: 10px;
 }
+
+.bx-hide-in-htmleditor {
+    display:none;
+}
+