Alex Trofimov 7 rokov pred
rodič
commit
a7ad48e68b

+ 20 - 0
inc/classes/BxDolForm.php

@@ -711,6 +711,7 @@ class BxDolForm extends BxDol implements iBxDolReplaceable
     static $TYPES_FILE = array('file' => 1);
 
     static $FUNC_SKIP_DOMAIN_CHECK = array('email' => 1, 'emails' => 1, 'emailexist' => 1, 'emailuniq' => 1, 'emailexistorempty' => 1, 'hostdomain' => 1, 'hostdomainchat' => 1, 'emailorempty' => 1);
+    static $FUNC_SKIP_MACROS_CHECK = array();
 
     protected $_aMarkers = array ();
 
@@ -1218,6 +1219,25 @@ class BxDolFormChecker
                 }
             }
 
+            // check for macros in text fields
+            $sCheckerFunc = isset($a['checker']['func']) ? strtolower($a['checker']['func']) : '';
+            if (
+                !isset(BxDolForm::$FUNC_SKIP_MACROS_CHECK[$sCheckerFunc]) && 
+                (!isset($a['skip_macros_check']) || false == $a['skip_macros_check']) && 
+                isset(BxDolForm::$TYPES_TEXT[$a['type']]) && 
+                bx_is_macros_in_content($val) && 
+                !isAdmin())
+            {
+                $aCheck = checkActionModule(bx_get_logged_profile_id(), 'use macros', 'system');
+                if ($aCheck[CHECK_ACTION_RESULT] !== CHECK_ACTION_RESULT_ALLOWED) {
+                    ++$iErrors;
+                    $aInputs[$k]['error'] = $aCheck[CHECK_ACTION_MESSAGE];
+                }
+                else {
+                    checkActionModule(bx_get_logged_profile_id(), 'use macros', 'system', true);
+                }
+            }
+
             if (!isset ($a['checker']))  {
                 if (isset(BxDolForm::$TYPES_CHECKBOX[$a['type']]))
                     $aInputs[$k]['checked'] = (isset($aInputs[$k]['value']) && $aInputs[$k]['value'] == $val);

+ 21 - 0
inc/classes/BxDolService.php

@@ -89,6 +89,27 @@ class BxDolService extends BxDol
         return self::call($a['module'], $a['method'], isset($a['params']) ? $a['params'] : array(), isset($a['class']) ? $a['class'] : 'Module', isset($a['ignore_cache']) ? $a['ignore_cache'] : false);
     }
 
+    public static function callMacro($s, $aMarkers = array(), $sReplaceIn = 'params')
+    {
+        if ($aMarkers)
+            $s = bx_replace_markers($s, $aMarkers);
+
+        if (!preg_match("/^([a-zA-Z0-9_\:]+)(.*)$/", $s, $aMatches))
+            return '<b></b>';
+
+        $a = explode(":", $aMatches[1]);
+        if (!isset($a[0]) || !isset($a[1]))
+            return '';
+
+        $aParams = array();
+        if (!empty($aMatches[2]))
+            $aParams = json_decode($aMatches[2]);
+        if (!$aParams)
+            $aParams = array();
+
+        return self::call($a[0], $a[1], $aParams, isset($a[3]) ? $a[3] : 'Module', isset($a[4]) && 'ignore_cache' == $a[4] ? true : false);
+    }
+
     /**
      * Check if string is serialized array
      */

+ 39 - 3
inc/utils.inc.php

@@ -227,15 +227,51 @@ function bx_process_output ($mixedData, $iDataType = BX_DATA_TEXT, $mixedParams
         return empty($mixedData) ? '' : gmdate("Y-m-d H:i", (int)$mixedData);
 
     case BX_DATA_HTML:
-        return bx_linkify_html($mixedData, 'class="' . BX_DOL_LINK_CLASS . '"');
+        $s = bx_linkify_html($mixedData, 'class="' . BX_DOL_LINK_CLASS . '"');
+        return $mixedParams && is_array($mixedParams) && in_array('no_process_macro', $mixedParams) ? $s : bx_process_macros($s);
     case BX_DATA_TEXT_MULTILINE:
-        return $mixedData;
+        $s = $mixedData;
+        return $mixedParams && is_array($mixedParams) && in_array('no_process_macros', $mixedParams) ? $s : bx_process_macros($s);
     case BX_DATA_TEXT:
     default:
-        return htmlspecialchars_adv($mixedData);
+        $s = htmlspecialchars_adv($mixedData);
+        return $mixedParams && is_array($mixedParams) && in_array('no_process_macros', $mixedParams) ? $s : bx_process_macros($s);
     }
 }
 
+function bx_is_macros_in_content (&$s) 
+{
+    return false === strpos($s, '{{!') ? false : true; 
+}
+
+/**
+ * This function converts macros upon text output. 
+ * Macros represents constructions like this:
+ * @code
+ * {{!module_name:function[param1, "param2"]}}
+ * @endcode
+ * For example, to display some content from module Posts:
+ * @code
+ * {{!bx_posts:get_search_result_unit[3]}}
+ * @endcode
+ * Only users which have "use macros" ACL action enabled can use this functionlity.
+ *
+ * @param $s text to process
+ * @return modified or not modified text
+ */
+function bx_process_macros ($s)
+{
+    if (!bx_is_macros_in_content($s))
+        return $s;
+
+    return preg_replace_callback(
+        "/{{!(.*?)}}/", 
+        function ($aMatches) {
+            return BxDolService::callMacro($aMatches[1]); 
+        }, 
+        $s);
+}
+
 /*
  * This function apply bx_process_input and then bx_process_output.
  * Use this function to output data immediately after receiving, without saving to database.

+ 9 - 1
install/sql/system.sql

@@ -754,6 +754,10 @@ INSERT INTO `sys_acl_actions` (`Module`, `Name`, `AdditionalParamName`, `Title`,
 ('system', 'post links', NULL, '_sys_acl_action_post_links', '_sys_acl_action_post_links_desc', 0, 0);
 SET @iIdActionPostLinks = LAST_INSERT_ID();
 
+INSERT INTO `sys_acl_actions` (`Module`, `Name`, `AdditionalParamName`, `Title`, `Desc`, `Countable`, `DisabledForLevels`) VALUES
+('system', 'use macros', NULL, '_sys_acl_action_use_macros', '_sys_acl_action_use_macros_desc', 0, 0);
+SET @iIdActionUseMacros = LAST_INSERT_ID();
+
 CREATE TABLE `sys_acl_actions_track` (
   `IDAction` int(10) unsigned NOT NULL DEFAULT '0',
   `IDMember` int(10) unsigned NOT NULL default '0',
@@ -906,7 +910,11 @@ INSERT INTO `sys_acl_matrix` (`IDLevel`, `IDAction`) VALUES
 (@iStandard, @iIdActionPostLinks),
 (@iModerator, @iIdActionPostLinks),
 (@iAdministrator, @iIdActionPostLinks),
-(@iPremium, @iIdActionPostLinks);
+(@iPremium, @iIdActionPostLinks),
+
+-- use macros
+(@iModerator, @iIdActionUseMacros),
+(@iAdministrator, @iIdActionUseMacros);
 
 
 CREATE TABLE `sys_acl_levels` (

+ 2 - 0
modules/boonex/russian/data/langs/system/ru.xml

@@ -1677,6 +1677,8 @@
     <string name="_sys_acl_action_pending"><![CDATA[В данный момент вы неактивный пользователь. Пожалуйста, попросите <a href="mailto:{7}">администратора сайта</a> активировать Вас, чтобы Вы могли <b>{1}</b>.]]></string>
 	<string name="_sys_acl_action_post_links"><![CDATA[Публикация ссылок]]></string>
     <string name="_sys_acl_action_post_links_desc"><![CDATA[Публикация ссылок в формах]]></string>
+	<string name="_sys_acl_action_use_macros"><![CDATA[Использовать макросы]]></string>
+    <string name="_sys_acl_action_use_macros_desc"><![CDATA[Использовать специально сконструированный вызов, для вставки динамического контента практически в любой текст]]></string>
 	<string name="_sys_acl_action_set_acl_level"><![CDATA[Назначить членство]]></string>
 	<string name="_sys_acl_action_set_acl_level_desc"><![CDATA[Назначить членство для профилей]]></string>
         <string name="_sys_acl_action_set_acl_as_privacy"><![CDATA[Использовать уровень членства в настройках приватности]]></string>

+ 1 - 1
template/scripts/BxBaseFormView.php

@@ -973,7 +973,7 @@ BLAH;
 
         $sAttrs = bx_convert_array2attrs($aAttrs, "bx-def-font-inputs bx-form-input-{$aInput['type']}" . ((isset($aInput['html']) and $aInput['html'] and $this->addHtmlEditor($aInput['html'], $aInput)) ? ' bx-form-input-html' : ''));
 
-        $sValue = isset($aInput['value']) ? bx_process_output((isset($aInput['html']) && $aInput['html']) || (isset($aInput['code']) && $aInput['code']) ? $aInput['value'] : strip_tags($aInput['value'])) : '';
+        $sValue = isset($aInput['value']) ? bx_process_output((isset($aInput['html']) && $aInput['html']) || (isset($aInput['code']) && $aInput['code']) ? $aInput['value'] : strip_tags($aInput['value']), BX_DATA_TEXT, array('no_process_macros')) : '';
 
         return "<textarea $sAttrs>$sValue</textarea>";
     }