فهرست منبع

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

Alex Trofimov 10 سال پیش
والد
کامیت
e18fddf929

+ 17 - 0
inc/classes/BxDolPayments.php

@@ -53,6 +53,23 @@ class BxDolPayments extends BxDol implements iBxDolSingleton
     	return true;
     }
 
+	public function getDetailsUrl()
+    {
+    	if(!BxDolRequest::serviceExists($this->_sActive, 'get_details_url', 'Details'))
+    		return '';
+
+    	return BxDolService::call($this->_sActive, 'get_details_url', array(), 'Details');
+    }
+
+    public function isAcceptingPayments($iVendorId, $sPaymentType = '')
+    {
+    	if(empty($this->_sActive) || !BxDolRequest::serviceExists($this->_sActive, 'is_accepting_payments'))
+    		return false;
+
+    	$aSrvParams = array($iVendorId, $sPaymentType);
+        return BxDolService::call($this->_sActive, 'is_accepting_payments', $aSrvParams);
+    }
+
 	public function getPayments()
     {
         $aPayments = array(

+ 11 - 0
inc/classes/BxDolSession.php

@@ -17,6 +17,8 @@ class BxDolSession extends BxDol implements iBxDolSingleton
     protected $iUserId;
     protected $aData;
 
+    protected $bAutoLogout;	//--- Auto logout with broken session
+
     private function __construct()
     {
         if (isset($GLOBALS['bxDolClasses'][get_class($this)]))
@@ -28,6 +30,8 @@ class BxDolSession extends BxDol implements iBxDolSingleton
         $this->sId = '';
         $this->iUserId = 0;
         $this->aData = array();
+
+        $this->bAutoLogout = true;
     }
 
     /**
@@ -61,6 +65,13 @@ class BxDolSession extends BxDol implements iBxDolSingleton
         if($this->exists($this->sId))
             return true;
 
+		/**
+		 * Force logout a logged in user if his session wasn't found and required to be automatically recreated.
+		 * It's needed to avoid problems when different users are logged in at the same time under one account. 
+		 */
+		if($this->bAutoLogout && isLogged())
+			bx_logout();
+
         $this->sId = genRndPwd(32, true);
 
         $aUrl = parse_url(BX_DOL_URL_ROOT);

+ 9 - 2
inc/js/jquery.dolPopup.js

@@ -200,7 +200,11 @@
                 }
                 
                 setTimeout(function () {
-                    o.onShow($el);                    
+                	if(typeof(o.onShow) == 'function')
+                		o.onShow($el);
+                    else if(typeof(o.onShow) == 'string')
+                    	eval(o.onShow);
+
                     $el.find('input[type=text]:first').focus(); // put cursor to the first input element
                 }, o.speed);
 
@@ -266,7 +270,10 @@
             $(window).off('resize.popupPointer');
             $(window).off('resize.popupFog');
 
-            o.onBeforeHide($el);
+            if(typeof(o.onBeforeHide) == 'function')
+            	o.onBeforeHide($el);
+            else if(typeof(o.onBeforeHide) == 'string')
+            	eval(o.onBeforeHide);
 
             $el.removeClass('bx-popup-active').addClass('bx-popup-inactive');
 

+ 4 - 8
inc/params.inc.php

@@ -10,7 +10,6 @@
 define('BX_DOL_START', microtime ());
 
 //--- Main URLs ---//
-
 define('BX_DOL_URL_PLUGINS', BX_DOL_URL_ROOT . 'plugins/');
 define('BX_DOL_URL_PLUGINS_PUBLIC', BX_DOL_URL_ROOT . 'plugins_public/');
 define('BX_DOL_URL_MODULES', BX_DOL_URL_ROOT . 'modules/');
@@ -18,7 +17,6 @@ define('BX_DOL_URL_CACHE_PUBLIC', BX_DOL_URL_ROOT . 'cache_public/');
 define('BX_DOL_URL_BASE', BX_DOL_URL_ROOT . 'template/');
 
 //--- Main Pathes ---//
-
 define('BX_DIRECTORY_PATH_INC', BX_DIRECTORY_PATH_ROOT . 'inc/');
 define('BX_DIRECTORY_PATH_BASE', BX_DIRECTORY_PATH_ROOT . 'template/');
 define('BX_DIRECTORY_PATH_CACHE', BX_DIRECTORY_PATH_ROOT . 'cache/');
@@ -32,7 +30,6 @@ define('BX_DIRECTORY_PATH_LOGS', BX_DIRECTORY_PATH_ROOT . 'logs/');
 define('BX_DIRECTORY_STORAGE', BX_DIRECTORY_PATH_ROOT . 'storage/');
 
 //--- System settings ---//
-
 define('BX_DOL_DIR_RIGHTS', 0777);
 define('BX_DOL_FILE_RIGHTS', 0666);
 
@@ -46,15 +43,17 @@ define('BX_DOL_TRANSCODER_OBJ_ICON_FAVICON', 'sys_icon_favicon');
 define('BX_DOL_TRANSCODER_OBJ_COVER', 'sys_cover');
 
 //--- Module types ---//
-
 if (!defined('BX_DOL_MODULE_TYPE_MODULE')) {
     define('BX_DOL_MODULE_TYPE_MODULE', 'module');
     define('BX_DOL_MODULE_TYPE_LANGUAGE', 'language');
     define('BX_DOL_MODULE_TYPE_TEMPLATE', 'template');
 }
 
-//--- Studio settings ---//
+//--- Payment types ---//
+define('BX_PAYMENT_TYPE_SINGLE', 'single');
+define('BX_PAYMENT_TYPE_RECURRING', 'recurring');
 
+//--- Studio settings ---//
 define('BX_DOL_STUDIO_FOLDER', 'studio');
 
 define('BX_DOL_URL_STUDIO', BX_DOL_URL_ROOT . BX_DOL_STUDIO_FOLDER . '/');
@@ -66,19 +65,16 @@ define('BX_DOL_DIR_STUDIO_CLASSES', BX_DOL_DIR_STUDIO . 'classes/');
 define('BX_DOL_DIR_STUDIO_BASE', BX_DOL_DIR_STUDIO . 'template/');
 
 //--- User Roles ---//
-
 define('BX_DOL_ROLE_GUEST', 0);
 define('BX_DOL_ROLE_MEMBER', 1);
 define('BX_DOL_ROLE_ADMIN', 2);
 
 //--- Profile Statuses ---//
-
 define('BX_PROFILE_STATUS_SUSPENDED', 'suspended'); ///< profile status - suspended, profile is syspended by admin/moderator and usually can't access the site
 define('BX_PROFILE_STATUS_ACTIVE', 'active'); ///< profile status - active, profile is active on the site
 define('BX_PROFILE_STATUS_PENDING', 'pending'); ///< profile status - pending, default method of approving is manual approving
 
 //--- Include files needed for basic functionality ---//
-
 require_once(BX_DIRECTORY_PATH_CLASSES . 'BxDol.php');
 require_once(BX_DIRECTORY_PATH_INC . 'utils.inc.php');
 require_once(BX_DIRECTORY_PATH_INC . 'version.inc.php');

+ 18 - 17
install/sql/system.sql

@@ -2745,26 +2745,27 @@ CREATE TABLE IF NOT EXISTS `sys_menu_templates` (
   `id` int(11) NOT NULL AUTO_INCREMENT,
   `template` varchar(255) NOT NULL,
   `title` varchar(255) NOT NULL,
+  `visible` tinyint(4) NOT NULL DEFAULT '1',
   PRIMARY KEY (`id`)
 ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
 
-INSERT INTO `sys_menu_templates` (`id`, `template`, `title`) VALUES
-(1, 'menu_empty.html', '_sys_menu_template_title_empty'),
-(2, 'menu_footer.html', '_sys_menu_template_title_footer'),
-(3, 'menu_horizontal.html', '_sys_menu_template_title_hor'),
-(4, 'menu_vertical_lite.html', '_sys_menu_template_title_ver_lite'),
-(5, 'menu_toolbar.html', '_sys_menu_template_title_toolbar'),
-(6, 'menu_vertical.html', '_sys_menu_template_title_ver'),
-(7, 'menu_floating_blocks.html', '_sys_menu_template_title_floating_blocks'),
-(8, 'menu_main_submenu.html', '_sys_menu_template_title_main_submenu'),
-(9, 'menu_buttons_hor.html', '_sys_menu_template_title_buttons_hor'),
-(10, 'menu_inline.html', '_sys_menu_template_title_inline'),
-(11, 'menu_interactive_vertical.html', '_sys_menu_template_title_interactive_vertical'),
-(12, 'menu_account_popup.html', '_sys_menu_template_title_account_popup'),
-(13, 'menu_account_notifications.html', '_sys_menu_template_title_account_notifications'),
-(14, 'menu_floating_blocks_big.html', '_sys_menu_template_title_floating_blocks_big'),
-(15, 'menu_custom.html', '_sys_menu_template_title_custom'),
-(16, 'menu_buttons_ver.html', '_sys_menu_template_title_buttons_ver');
+INSERT INTO `sys_menu_templates` (`id`, `template`, `title`, `visible`) VALUES
+(1, 'menu_empty.html', '_sys_menu_template_title_empty', 1),
+(2, 'menu_footer.html', '_sys_menu_template_title_footer', 0),
+(3, 'menu_horizontal.html', '_sys_menu_template_title_hor', 1),
+(4, 'menu_vertical_lite.html', '_sys_menu_template_title_ver_lite', 1),
+(5, 'menu_toolbar.html', '_sys_menu_template_title_toolbar', 0),
+(6, 'menu_vertical.html', '_sys_menu_template_title_ver', 1),
+(7, 'menu_floating_blocks.html', '_sys_menu_template_title_floating_blocks', 1),
+(8, 'menu_main_submenu.html', '_sys_menu_template_title_main_submenu', 0),
+(9, 'menu_buttons_hor.html', '_sys_menu_template_title_buttons_hor', 1),
+(10, 'menu_inline.html', '_sys_menu_template_title_inline', 1),
+(11, 'menu_interactive_vertical.html', '_sys_menu_template_title_interactive_vertical', 1),
+(12, 'menu_account_popup.html', '_sys_menu_template_title_account_popup', 0),
+(13, 'menu_account_notifications.html', '_sys_menu_template_title_account_notifications', 0),
+(14, 'menu_floating_blocks_big.html', '_sys_menu_template_title_floating_blocks_big', 1),
+(15, 'menu_custom.html', '_sys_menu_template_title_custom', 0),
+(16, 'menu_buttons_ver.html', '_sys_menu_template_title_buttons_ver', 1);
 
 CREATE TABLE IF NOT EXISTS `sys_objects_menu` (
   `id` int(11) NOT NULL AUTO_INCREMENT,

+ 33 - 0
modules/base/payment/classes/BxBaseModPaymentDetails.php

@@ -0,0 +1,33 @@
+<?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    BasePayment Base classes for Payment like modules
+ * @ingroup     TridentModules
+ *
+ * @{
+ */
+
+class BxBaseModPaymentDetails extends BxDol
+{
+	protected $MODULE;
+	protected $_oModule;
+
+	function __construct()
+    {
+        parent::__construct();
+
+        $this->_oModule = BxDolModule::getInstance($this->MODULE);
+    }
+
+	public function serviceGetDetailsUrl()
+    {
+    	if(!$this->_oModule->isLogged())
+            return '';
+
+    	return  $this->_oModule->_oConfig->getUrl('URL_DETAILS');
+    }
+}
+
+/** @} */

+ 2 - 0
modules/boonex/market/classes/BxMarketConfig.php

@@ -46,9 +46,11 @@ class BxMarketConfig extends BxBaseModTextConfig
             'FIELD_TEXT_ID' => 'product-text',
         	'FIELD_CATEGORY' => 'cat',
         	'FIELD_HEADER_BEG_SINGLE' => 'header_beg_single',
+        	'FIELD_WARNING_SINGLE' => 'warning_single',
         	'FIELD_PRICE_SINGLE' => 'price_single',
         	'FIELD_HEADER_END_SINGLE' => 'header_end_single',
         	'FIELD_HEADER_BEG_RECURRING' => 'header_beg_recurring',
+        	'FIELD_WARNING_RECURRING' => 'warning_recurring',
         	'FIELD_PRICE_RECURRING' => 'price_recurring',
         	'FIELD_DURATION_RECURRING' => 'duration_recurring',
         	'FIELD_HEADER_END_RECURRING' => 'header_end_recurring',

+ 21 - 6
modules/boonex/market/classes/BxMarketFormEntry.php

@@ -21,6 +21,8 @@ class BxMarketFormEntry extends BxBaseModTextFormEntry
 
         $CNF = &$this->_oModule->_oConfig->CNF;
 
+        $iProfileId = bx_get_logged_profile_id();
+
         if(isset($this->aInputs[$CNF['FIELD_TITLE']], $this->aInputs[$CNF['FIELD_NAME']])) {
         	$sJsObject = $this->_oModule->_oConfig->getJsObject('entry');
 
@@ -38,33 +40,46 @@ class BxMarketFormEntry extends BxBaseModTextFormEntry
             $this->aInputs[$CNF['FIELD_FILE']]['ghost_template'] = '';
         }
 
-        if($this->_oModule->_oDb->getParam($CNF['OPTION_ENABLE_RECURRING']) != 'on') {
+        $bRecurring = $this->_oModule->_oDb->getParam($CNF['OPTION_ENABLE_RECURRING']) == 'on';
+        if(!$bRecurring) {
         	$this->aInputs[$CNF['FIELD_DURATION_RECURRING']]['type'] = 'hidden';
 			$this->aInputs[$CNF['FIELD_PRICE_RECURRING']]['type'] = 'hidden';
 			$this->aInputs[$CNF['FIELD_PRICE_RECURRING']]['value'] = 0;
 
-			unset($this->aInputs[$CNF['FIELD_HEADER_BEG_SINGLE']]);
-			unset($this->aInputs[$CNF['FIELD_HEADER_END_SINGLE']]);
 			unset($this->aInputs[$CNF['FIELD_HEADER_BEG_RECURRING']]);
 			unset($this->aInputs[$CNF['FIELD_HEADER_END_RECURRING']]);
         }
 
+        $oPayment = BxDolPayments::getInstance();
+        if(isset($this->aInputs[$CNF['FIELD_WARNING_SINGLE']])) {
+	        if(!$oPayment->isAcceptingPayments($iProfileId, BX_PAYMENT_TYPE_SINGLE)) 
+	        	$this->aInputs[$CNF['FIELD_WARNING_SINGLE']]['value'] = MsgBox(_t($this->aInputs[$CNF['FIELD_WARNING_SINGLE']]['value'], $oPayment->getDetailsUrl()));
+	        else 
+	        	unset($this->aInputs[$CNF['FIELD_WARNING_SINGLE']]);
+        }
+
+        if(isset($this->aInputs[$CNF['FIELD_WARNING_RECURRING']])) {
+	        if($bRecurring && !$oPayment->isAcceptingPayments($iProfileId, BX_PAYMENT_TYPE_RECURRING))
+	        	$this->aInputs[$CNF['FIELD_WARNING_RECURRING']]['value'] = MsgBox(_t($this->aInputs[$CNF['FIELD_WARNING_RECURRING']]['value'], $oPayment->getDetailsUrl()));
+	        else 
+	        	unset($this->aInputs[$CNF['FIELD_WARNING_RECURRING']]);
+        }
+
 		if(isset($this->aInputs[$CNF['FIELD_ALLOW_PURCHASE_TO']]))
 			$this->aInputs[$CNF['FIELD_ALLOW_PURCHASE_TO']] = BxDolPrivacy::getGroupChooser($CNF['OBJECT_PRIVACY_PURCHASE']);
 
-		$iOwnerId = bx_get_logged_profile_id();
 		$aDynamicGroups = array(
 			array ('key' => '', 'value' => '----'),
 			array ('key' => 'c', 'value' => _t('_bx_market_privacy_group_customers'))
 		);
 
 		if(isset($this->aInputs[$CNF['FIELD_ALLOW_COMMENT_TO']])) {
-			$this->aInputs[$CNF['FIELD_ALLOW_COMMENT_TO']] = BxDolPrivacy::getGroupChooser($CNF['OBJECT_PRIVACY_COMMENT'], $iOwnerId, array('dynamic_groups' => $aDynamicGroups));
+			$this->aInputs[$CNF['FIELD_ALLOW_COMMENT_TO']] = BxDolPrivacy::getGroupChooser($CNF['OBJECT_PRIVACY_COMMENT'], $iProfileId, array('dynamic_groups' => $aDynamicGroups));
 			$this->aInputs[$CNF['FIELD_ALLOW_COMMENT_TO']]['db']['pass'] = 'Xss';
 		}
 
 		if(isset($this->aInputs[$CNF['FIELD_ALLOW_VOTE_TO']])) {
-			$this->aInputs[$CNF['FIELD_ALLOW_VOTE_TO']] = BxDolPrivacy::getGroupChooser($CNF['OBJECT_PRIVACY_VOTE'], $iOwnerId, array('dynamic_groups' => $aDynamicGroups));
+			$this->aInputs[$CNF['FIELD_ALLOW_VOTE_TO']] = BxDolPrivacy::getGroupChooser($CNF['OBJECT_PRIVACY_VOTE'], $iProfileId, array('dynamic_groups' => $aDynamicGroups));
 			$this->aInputs[$CNF['FIELD_ALLOW_VOTE_TO']]['db']['pass'] = 'Xss';
 		}
     }

+ 4 - 1
modules/boonex/market/classes/BxMarketModule.php

@@ -41,8 +41,11 @@ class BxMarketModule extends BxBaseModTextModule
 
     public function serviceEntityCreate ()
     {
-    	$this->_oTemplate->addJs(array('entry.js'));
+    	$oPayments = BxDolPayments::getInstance();
+    	if(!$oPayments->isAcceptingPayments($this->_iProfileId))
+    		return MsgBox(_t('_bx_market_err_not_accept_payments', $oPayments->getDetailsUrl()));
 
+    	$this->_oTemplate->addJs(array('entry.js'));
     	return $this->_oTemplate->getJsCode('entry') . parent::serviceEntityCreate();
     }
 

+ 3 - 2
modules/boonex/market/install/langs/en.xml

@@ -245,8 +245,6 @@
 	<string name="_bx_market_grid_txt_lcs_type_single"><![CDATA[one-time]]></string>
 	<string name="_bx_market_grid_txt_lcs_type_recurring"><![CDATA[recurring]]></string>
 	<string name="_bx_market_grid_txt_lcs_never"><![CDATA[never]]></string>
-	<string name=""><![CDATA[]]></string>
-	<string name=""><![CDATA[]]></string>
 
     <string name="_bx_market_pre_lists_cats"><![CDATA[Product categories]]></string>
     <string name="_bx_market_cat_administration"><![CDATA[Administration]]></string>
@@ -305,6 +303,9 @@
     <string name="_bx_market_vote_counter"><![CDATA[{0} ratings]]></string>
 
 	<string name="_bx_market_err_access_denied"><![CDATA[Access denied.]]></string>
+	<string name="_bx_market_err_not_accept_payments"><![CDATA[You need to activate at least one payment provider. You may do it via My Account menu -> Orders page -> <a href="{0}">Settings</a> tab.]]></string>
+	<string name="_bx_market_err_not_accept_payments_single"><![CDATA[You need to activate at least one payment provider, which is working with Shopping Cart. You may do it via My Account menu -> Orders page -> <a href="{0}">Settings</a> tab.]]></string>
+	<string name="_bx_market_err_not_accept_payments_recurring"><![CDATA[You need to activate at least one payment provider, which is working with Subscriptions. You may do it via My Account menu -> Orders page -> <a href="{0}">Settings</a> tab.]]></string>
 
     <string name="_bx_market_txt_all_entries_by"><![CDATA[<a href="{0}">All Products by {1} ({2})</a>]]></string>
     <string name="_bx_market_txt_category"><![CDATA[Category:]]></string>

+ 38 - 32
modules/boonex/market/install/sql/install.sql

@@ -271,7 +271,9 @@ INSERT INTO `sys_form_inputs`(`object`, `module`, `name`, `value`, `values`, `ch
 ('bx_market', 'bx_market', 'header_beg_privacy', '', '', 0, 'block_header', '_bx_market_form_entry_input_sys_header_beg_privacy', '_bx_market_form_entry_input_header_beg_privacy', '', 0, 1, 0, '', '', '', '', '', '', '', '', 1, 0),
 ('bx_market', 'bx_market', 'header_end_single', '', '', 0, 'block_end', '_bx_market_form_entry_input_sys_header_end_single', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
 ('bx_market', 'bx_market', 'header_end_recurring', '', '', 0, 'block_end', '_bx_market_form_entry_input_sys_header_end_recurring', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
-('bx_market', 'bx_market', 'header_end_privacy', '', '', 0, 'block_end', '_bx_market_form_entry_input_sys_header_end_privacy', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0);
+('bx_market', 'bx_market', 'header_end_privacy', '', '', 0, 'block_end', '_bx_market_form_entry_input_sys_header_end_privacy', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
+('bx_market', 'bx_market', 'warning_single', '_bx_market_err_not_accept_payments_single', '', 0, 'value', '_bx_market_form_entry_input_sys_warning_single', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
+('bx_market', 'bx_market', 'warning_recurring', '_bx_market_err_not_accept_payments_recurring', '', 0, 'value', '_bx_market_form_entry_input_sys_warning_recurring', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0);
 
 
 INSERT INTO `sys_form_display_inputs`(`display_name`, `input_name`, `visible_for_levels`, `active`, `order`) VALUES 
@@ -283,22 +285,24 @@ INSERT INTO `sys_form_display_inputs`(`display_name`, `input_name`, `visible_for
 ('bx_market_entry_add', 'pictures', 2147483647, 1, 6),
 ('bx_market_entry_add', 'files', 2147483647, 1, 7),
 ('bx_market_entry_add', 'header_beg_single', 2147483647, 1, 8),
-('bx_market_entry_add', 'price_single', 2147483647, 1, 9),
-('bx_market_entry_add', 'header_end_single', 2147483647, 1, 10),
-('bx_market_entry_add', 'header_beg_recurring', 2147483647, 1, 11),
-('bx_market_entry_add', 'duration_recurring', 2147483647, 1, 12),
-('bx_market_entry_add', 'price_recurring', 2147483647, 1, 13),
-('bx_market_entry_add', 'header_end_recurring', 2147483647, 1, 14),
-('bx_market_entry_add', 'header_beg_privacy', 2147483647, 1, 15),
-('bx_market_entry_add', 'allow_view_to', 2147483647, 1, 16),
-('bx_market_entry_add', 'allow_purchase_to', 2147483647, 1, 17),
-('bx_market_entry_add', 'allow_comment_to', 2147483647, 1, 18),
-('bx_market_entry_add', 'allow_vote_to', 2147483647, 1, 19),
-('bx_market_entry_add', 'header_end_privacy', 2147483647, 1, 20),
-('bx_market_entry_add', 'notes', 2147483647, 1, 21),
-('bx_market_entry_add', 'location', 2147483647, 1, 22),
-('bx_market_entry_add', 'do_submit', 2147483647, 0, 23),
-('bx_market_entry_add', 'do_publish', 2147483647, 1, 24),
+('bx_market_entry_add', 'warning_single', 2147483647, 1, 9),
+('bx_market_entry_add', 'price_single', 2147483647, 1, 10),
+('bx_market_entry_add', 'header_end_single', 2147483647, 1, 11),
+('bx_market_entry_add', 'header_beg_recurring', 2147483647, 1, 12),
+('bx_market_entry_add', 'warning_recurring', 2147483647, 1, 13),
+('bx_market_entry_add', 'duration_recurring', 2147483647, 1, 14),
+('bx_market_entry_add', 'price_recurring', 2147483647, 1, 15),
+('bx_market_entry_add', 'header_end_recurring', 2147483647, 1, 16),
+('bx_market_entry_add', 'header_beg_privacy', 2147483647, 1, 17),
+('bx_market_entry_add', 'allow_view_to', 2147483647, 1, 18),
+('bx_market_entry_add', 'allow_purchase_to', 2147483647, 1, 19),
+('bx_market_entry_add', 'allow_comment_to', 2147483647, 1, 20),
+('bx_market_entry_add', 'allow_vote_to', 2147483647, 1, 21),
+('bx_market_entry_add', 'header_end_privacy', 2147483647, 1, 22),
+('bx_market_entry_add', 'notes', 2147483647, 1, 23),
+('bx_market_entry_add', 'location', 2147483647, 1, 24),
+('bx_market_entry_add', 'do_submit', 2147483647, 0, 25),
+('bx_market_entry_add', 'do_publish', 2147483647, 1, 26),
 
 ('bx_market_entry_delete', 'notes', 2147483647, 0, 0),
 ('bx_market_entry_delete', 'location', 2147483647, 0, 0),
@@ -334,21 +338,23 @@ INSERT INTO `sys_form_display_inputs`(`display_name`, `input_name`, `visible_for
 ('bx_market_entry_edit', 'pictures', 2147483647, 1, 7),
 ('bx_market_entry_edit', 'files', 2147483647, 1, 8),
 ('bx_market_entry_edit', 'header_beg_single', 2147483647, 1, 9),
-('bx_market_entry_edit', 'price_single', 2147483647, 1, 10),
-('bx_market_entry_edit', 'header_end_single', 2147483647, 1, 11),
-('bx_market_entry_edit', 'header_beg_recurring', 2147483647, 1, 12),
-('bx_market_entry_edit', 'duration_recurring', 2147483647, 1, 13),
-('bx_market_entry_edit', 'price_recurring', 2147483647, 1, 14),
-('bx_market_entry_edit', 'header_end_recurring', 2147483647, 1, 15),
-('bx_market_entry_edit', 'header_beg_privacy', 2147483647, 1, 16),
-('bx_market_entry_edit', 'allow_view_to', 2147483647, 1, 17),
-('bx_market_entry_edit', 'allow_purchase_to', 2147483647, 1, 18),
-('bx_market_entry_edit', 'allow_comment_to', 2147483647, 1, 19),
-('bx_market_entry_edit', 'allow_vote_to', 2147483647, 1, 20),
-('bx_market_entry_edit', 'header_end_privacy', 2147483647, 1, 21),
-('bx_market_entry_edit', 'notes', 2147483647, 1, 22),
-('bx_market_entry_edit', 'location', 2147483647, 1, 23),
-('bx_market_entry_edit', 'do_submit', 2147483647, 1, 24),
+('bx_market_entry_edit', 'warning_single', 2147483647, 1, 10),
+('bx_market_entry_edit', 'price_single', 2147483647, 1, 11),
+('bx_market_entry_edit', 'header_end_single', 2147483647, 1, 12),
+('bx_market_entry_edit', 'header_beg_recurring', 2147483647, 1, 13),
+('bx_market_entry_edit', 'warning_recurring', 2147483647, 1, 14),
+('bx_market_entry_edit', 'duration_recurring', 2147483647, 1, 15),
+('bx_market_entry_edit', 'price_recurring', 2147483647, 1, 16),
+('bx_market_entry_edit', 'header_end_recurring', 2147483647, 1, 17),
+('bx_market_entry_edit', 'header_beg_privacy', 2147483647, 1, 18),
+('bx_market_entry_edit', 'allow_view_to', 2147483647, 1, 19),
+('bx_market_entry_edit', 'allow_purchase_to', 2147483647, 1, 20),
+('bx_market_entry_edit', 'allow_comment_to', 2147483647, 1, 21),
+('bx_market_entry_edit', 'allow_vote_to', 2147483647, 1, 22),
+('bx_market_entry_edit', 'header_end_privacy', 2147483647, 1, 23),
+('bx_market_entry_edit', 'notes', 2147483647, 1, 24),
+('bx_market_entry_edit', 'location', 2147483647, 1, 25),
+('bx_market_entry_edit', 'do_submit', 2147483647, 1, 26),
 
 ('bx_market_entry_view', 'notes', 2147483647, 0, 0),
 ('bx_market_entry_view', 'location', 2147483647, 0, 0),

+ 1 - 6
modules/boonex/payment/classes/BxPaymentDetails.php

@@ -19,11 +19,8 @@ class BxPaymentDetailsFormCheckerHelper extends BxDolFormCheckerHelper
     }
 }
 
-class BxPaymentDetails extends BxDol
+class BxPaymentDetails extends BxBaseModPaymentDetails
 {
-    protected $MODULE;
-	protected $_oModule;
-
 	protected $_sLangsPrefix;
     protected $_bCollapseFirst;
 
@@ -33,8 +30,6 @@ class BxPaymentDetails extends BxDol
 
     	parent::__construct();
 
-    	$this->_oModule = BxDolModule::getInstance($this->MODULE);
-
     	$this->_sLangsPrefix = $this->_oModule->_oConfig->getPrefix('langs');
         $this->_bCollapseFirst = true;
     }

+ 24 - 3
modules/boonex/payment/classes/BxPaymentModule.php

@@ -9,9 +9,6 @@
  * @{
  */
 
-define('BX_PAYMENT_TYPE_SINGLE', 'single');
-define('BX_PAYMENT_TYPE_RECURRING', 'recurring');
-
 define('BX_PAYMENT_ORDERS_TYPE_PENDING', 'pending');
 define('BX_PAYMENT_ORDERS_TYPE_PROCESSED', 'processed');
 define('BX_PAYMENT_ORDERS_TYPE_SUBSCRIPTION', 'subscription');
@@ -127,6 +124,30 @@ class BxPaymentModule extends BxBaseModPaymentModule
     /**
      * Payment Details Methods
      */
+    public function serviceIsAcceptingPayments($iVendorId, $sPaymentType = '')
+    {
+    	$bResult = false;
+
+    	switch($sPaymentType) {
+    		case BX_PAYMENT_TYPE_SINGLE:
+    			$aProvidersCart = $this->_oDb->getVendorInfoProvidersCart($iVendorId);
+    			$bResult = !empty($aProvidersCart);
+    			break;
+
+    		case BX_PAYMENT_TYPE_RECURRING:
+    			$aProvidersSubscription = $this->_oDb->getVendorInfoProvidersSubscription($iVendorId);
+    			$bResult = !empty($aProvidersSubscription);
+    			break;
+
+    		default:
+    			$aProvidersCart = $this->_oDb->getVendorInfoProvidersCart($iVendorId);
+    			$aProvidersSubscription = $this->_oDb->getVendorInfoProvidersSubscription($iVendorId);
+    			$bResult = !empty($aProvidersCart) || !empty($aProvidersSubscription);
+    	}
+
+		return $bResult;
+    }
+
     public function serviceGetOptionsSiteAdmin()
     {
         $aResult = array(

+ 2 - 0
modules/boonex/payment/install/langs/en.xml

@@ -147,6 +147,8 @@
 	<string name="_bx_payment_err_inactive_vendor"><![CDATA[The vendor status is not active.]]></string>
 	<string name="_bx_payment_err_incorrect_provider"><![CDATA[Incorrect or unavailable payment provider.]]></string>
 	<string name="_bx_payment_err_not_accept_payments"><![CDATA[The vendor does not accept payments.]]></string>
+	<string name="_bx_payment_err_not_accept_payments_single"><![CDATA[The vendor does not accept payments via shopping cart.]]></string>
+	<string name="_bx_payment_err_not_accept_payments_recurring"><![CDATA[The vendor does not work with subscriptions.]]></string>
 	<string name="_bx_payment_err_nothing_selected"><![CDATA[You need to select at least one item.]]></string>
 	<string name="_bx_payment_err_self_purchase"><![CDATA[You cannot purchase your own item. It's just a bad luck thing, you know.]]></string>
 	<string name="_bx_payment_err_required_login"><![CDATA[You need to login.]]></string>

+ 3 - 0
modules/boonex/russian/data/langs/bx_market/ru.xml

@@ -301,6 +301,9 @@
 	<string name="_bx_market_vote_counter"><![CDATA[{0} голосов]]></string>
 
 	<string name="_bx_market_err_access_denied"><![CDATA[Доступ запрещен.]]></string>
+	<string name="_bx_market_err_not_accept_payments"><![CDATA[Вам необходимо активировать хотя бы одину платежную систему. Вы можете сделать это через меню Мой аккаунт -> страница Заказы -> <a href="{0}">вкладка Настройки</a>.]]></string>
+	<string name="_bx_market_err_not_accept_payments_single"><![CDATA[Вам необходимо активировать хотя бы одину платежную систему, работающую с корзиной. Вы можете сделать это через меню Мой аккаунт -> страница Заказы -> <a href="{0}">вкладка Настройки</a>.]]></string>
+	<string name="_bx_market_err_not_accept_payments_recurring"><![CDATA[Вам необходимо активировать хотя бы одину платежную систему, работающую с подписками. Вы можете сделать это через меню Мой аккаунт -> страница Заказы -> <a href="{0}">вкладка Настройки</a>.]]></string>
 
     <string name="_bx_market_txt_all_entries_by"><![CDATA[<a href="{0}">Все продукты от {1} ({2})</a>]]></string>
     <string name="_bx_market_txt_category"><![CDATA[Категория:]]></string>

+ 9 - 1
studio/classes/BxDolStudioNavigationQuery.php

@@ -177,6 +177,13 @@ class BxDolStudioNavigationQuery extends BxDolDb
            $sOrderClause = "ORDER BY `tmt`.`title` ASC";
 
         switch($aParams['type']) {
+        	case 'all_visible_key_id':
+        		$aMethod['name'] = 'getAllWithKey';
+        		$aMethod['params'][1] = 'id';
+
+        		$sWhereClause .= "AND `tmt`.`visible`='1'";
+                break;
+
             case 'all':
                 break;
         }
@@ -184,7 +191,8 @@ class BxDolStudioNavigationQuery extends BxDolDb
         $aMethod['params'][0] = "SELECT " . ($bReturnCount ? "SQL_CALC_FOUND_ROWS" : "") . "
                 `tmt`.`id` AS `id`,
                 `tmt`.`template` AS `template`,
-                `tmt`.`title` AS `title`" . $sSelectClause . "
+                `tmt`.`title` AS `title`,
+                `tmt`.`visible` AS `visible`" . $sSelectClause . "
             FROM `sys_menu_templates` AS `tmt` " . $sJoinClause . "
             WHERE 1 " . $sWhereClause . " " . $sGroupClause . " " . $sOrderClause . " " . $sLimitClause;
         $aItems = call_user_func_array(array($this, $aMethod['name']), $aMethod['params']);

+ 20 - 0
studio/js/builder_page.js

@@ -178,10 +178,30 @@ BxDolStudioBuilderPage.prototype.onChangeVisibleFor = function(oSelect) {
 	$(oSelect).parents('form:first').find('#bx-form-element-visible_for_levels').bx_anim($(oSelect).val() == 'all' ? 'hide' : 'show', this.sAnimationEffect, this.iAnimationSpeed);
 };
 
+BxDolStudioBuilderPage.prototype.onEditBlockBeforeShow = function(oPopup) {
+	var oContentEditor = CodeMirror.fromTextArea($(oPopup).find("textarea[name = 'content']").get(0), {
+        lineNumbers: true,
+        mode: "htmlmixed",
+        htmlMode: true,
+        matchBrackets: true
+    }).on('blur', function(oEditor) {
+    	oEditor.save();
+    });
+};
+
 BxDolStudioBuilderPage.prototype.onEditBlock = function(oData) {
 	window.location.href = this.parsePageUrl({page: this.sPage});
 };
 
+BxDolStudioBuilderPage.prototype.onEditBlockCancel = function(oButton) {
+	var oTextarea = $(oButton).parents('form:first').find('textarea.bx-form-input-html');
+	if(oTextarea.length > 0 && typeof tinymce == 'object') {
+		oTextarea.tinymce().remove();
+	}
+
+	$('.bx-popup-applied:visible').dolPopupHide();
+};
+
 BxDolStudioBuilderPage.prototype.deleteBlock = function(iId) {
 	if(!confirm(aDolLang['_adm_bp_wrn_page_block_delete']))
 		return;

+ 20 - 10
studio/js/page.js

@@ -10,6 +10,13 @@ function BxDolStudioPage(oOptions) {
     this.sObjName = oOptions.sObjName == undefined ? 'oBxDolStudioPage' : oOptions.sObjName;
     this.sAnimationEffect = oOptions.sAnimationEffect == undefined ? 'slide' : oOptions.sAnimationEffect;
     this.iAnimationSpeed = oOptions.iAnimationSpeed == undefined ? 'slow' : oOptions.iAnimationSpeed;
+    this.oPopupOptions = {
+		fog: {
+			color: '#fff',
+			opacity: .7
+	    },
+	    closeOnOuterClick: false
+    };
 }
 
 BxDolStudioPage.prototype.processJson = function (oData) {
@@ -23,16 +30,19 @@ BxDolStudioPage.prototype.processJson = function (oData) {
 
     //--- Show Popup
     if(oData && oData.popup != undefined) {
-    	var oPopup = $(oData.popup).hide(); 
-
-    	$('#' + oPopup.attr('id')).remove();
-        oPopup.prependTo('body').dolPopup({
-            fog: {
-				color: '#fff',
-				opacity: .7
-            },
-            closeOnOuterClick: false
-        });
+    	if (typeof(oData.popup) == 'object') {
+    		var oPopup = $(oData.popup.html).hide(); 
+    		var oPopupOptions = $.extend({}, this.oPopupOptions, oData.popup.options);
+
+	    	$('#' + oPopup.attr('id')).remove();
+	        oPopup.prependTo('body').dolPopup(oPopupOptions);
+    	}
+    	else {
+	    	var oPopup = $(oData.popup).hide(); 
+	
+	    	$('#' + oPopup.attr('id')).remove();
+	        oPopup.prependTo('body').dolPopup(this.oPopupOptions);
+    	}
     }
 
     //--- Evaluate JS code

+ 14 - 8
studio/template/scripts/BxBaseStudioBuilderPage.php

@@ -73,12 +73,17 @@ class BxBaseStudioBuilderPage extends BxDolStudioBuilderPage
 				$oUploader->addCssJs();
 		}
 
-        return array_merge(parent::getPageCss(), array('page_layouts.css', 'builder_page.css'));
+        return array_merge(parent::getPageCss(), array(
+        	BX_DIRECTORY_PATH_PLUGINS_PUBLIC . 'codemirror/|codemirror.css',
+        	'page_layouts.css', 
+        	'builder_page.css'
+        ));
     }
 
     function getPageJs()
     {
         return array_merge(parent::getPageJs(), array(
+        	'codemirror/codemirror.min.js',
             'jquery-ui/jquery.ui.core.min.js',
             'jquery-ui/jquery.ui.widget.min.js',
             'jquery-ui/jquery.ui.mouse.min.js',
@@ -518,6 +523,7 @@ class BxBaseStudioBuilderPage extends BxDolStudioBuilderPage
 
             $bResult = true;
             foreach($aBlocks as $aBlock) {
+            	$sModule = $aBlock['module'];
                 $sTitleKey = $this->getSystemName($aBlock['title'] . '_' . time());
                 $aTitleValues = $oLanguage->getLanguageString($aBlock['title']);
 
@@ -526,7 +532,7 @@ class BxBaseStudioBuilderPage extends BxDolStudioBuilderPage
                 $aBlock['cell_id'] = 1;
                 $aBlock['module'] = $this->getBlockModule($aBlock);
                 $aBlock['title'] = $sTitleKey;
-				$aBlock['copyable'] = 0;
+				$aBlock['copyable'] = $sModule == BX_DOL_STUDIO_BP_SKELETONS ? 1 : 0;
                 $aBlock['deletable'] = 1;
 
                 //--- Process Lang copy
@@ -682,7 +688,7 @@ class BxBaseStudioBuilderPage extends BxDolStudioBuilderPage
                     ),
                     'required' => '0',
                     'attrs' => array(
-                        'onchange' => $this->getPageJsObject() . '.onChangeVisibleFor(this)'
+                        'onchange' => $sJsObject . '.onChangeVisibleFor(this)'
                     ),
                     'db' => array (
                         'pass' => 'Xss',
@@ -719,14 +725,14 @@ class BxBaseStudioBuilderPage extends BxDolStudioBuilderPage
                     array(
                         'type' => 'submit',
                         'name' => 'do_submit',
-                        'value' => _t('_adm_bp_btn_block_save'),
+                        'value' => _t('_adm_bp_btn_block_save')
                     ),
                     array (
                         'type' => 'reset',
                         'name' => 'close',
                         'value' => _t('_adm_bp_btn_block_cancel'),
                         'attrs' => array(
-                            'onclick' => "$('.bx-popup-applied:visible').dolPopupHide()",
+                            'onclick' => $sJsObject . '.onEditBlockCancel(this)',
                             'class' => 'bx-def-margin-sec-left',
                         ),
                     )
@@ -749,7 +755,7 @@ class BxBaseStudioBuilderPage extends BxDolStudioBuilderPage
                 'name' => 'close',
                 'value' => _t('_adm_bp_btn_block_delete'),
                 'attrs' => array(
-                    'onclick' => $this->getPageJsObject() . ".deleteBlock(" . $aBlock['id'] . ")",
+                    'onclick' => $sJsObject . '.deleteBlock(' . $aBlock['id'] . ')',
                     'class' => 'bx-def-margin-sec-left',
                 ),
             );
@@ -772,7 +778,7 @@ class BxBaseStudioBuilderPage extends BxDolStudioBuilderPage
             'form' => $oForm->getCode(true)
         )));
 
-        return array('popup' => $sContent);
+        return array('popup' => array('html' => $sContent, 'options' => array('onBeforeShow' => $sJsObject . '.onEditBlockBeforeShow($el)')));
     }
 
     protected function actionBlockDelete()
@@ -1271,7 +1277,7 @@ class BxBaseStudioBuilderPage extends BxDolStudioBuilderPage
                         'required' => '0',
                 		'code' => 1,
                         'db' => array (
-                            'pass' => 'Xss',
+                            'pass' => 'XssHtml',
                         ),
                     ),
                 );

+ 6 - 1
studio/template/scripts/BxBaseStudioNavigationMenus.php

@@ -366,7 +366,7 @@ class BxBaseStudioNavigationMenus extends BxDolStudioNavigationMenus
             $aForm['inputs']['set_name']['values'][] = array('key' => $sSet['name'], 'value' => _t($sSet['title']));
 
         $aTemplates = array();
-        $this->oDb->getTemplates(array('type' => 'all'), $aTemplates, false);
+        $this->oDb->getTemplates(array('type' => 'all_visible_key_id'), $aTemplates, false);
         foreach($aTemplates as $aTemplate)
             $aForm['inputs']['template_id']['values'][] = array('key' => $aTemplate['id'], 'value' => _t($aTemplate['title']));
 
@@ -380,6 +380,11 @@ class BxBaseStudioNavigationMenus extends BxDolStudioNavigationMenus
             case 'edit':
                 $aForm['form_attrs']['id'] .= 'edit';
                 $aForm['inputs']['set_title']['checker']['func'] = 'UniqueSet';
+
+                $iTemplateId = (int)$aForm['inputs']['template_id']['value'];
+                if(!empty($iTemplateId) && !array_key_exists($iTemplateId, $aTemplates))
+                	$aForm['inputs']['template_id']['type'] = 'hidden';
+
                 $aForm['inputs']['controls'][0]['value'] = _t('_adm_nav_btn_menus_save');
                 break;
         }

+ 3 - 1
template/scripts/BxBaseEditorTinyMCE.php

@@ -193,7 +193,9 @@ class BxBaseEditorTinyMCE extends BxDolEditor
                         });
                     });
                 } else {
-                    $sInitEditor
+                	setTimeout(function () {
+                    	$sInitEditor
+                    }, 10); // wait while html is rendered in case of dynamic adding html with tinymce
                 }
             </script>";