Преглед изворни кода

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

Alex Trofimov пре 12 година
родитељ
комит
a8f96c37cc
41 измењених фајлова са 598 додато и 96 уклоњено
  1. 1 1
      inc/classes/BxDolTemplate.php
  2. 10 3
      inc/utils.inc.php
  3. 5 1
      install/sql/v70.sql
  4. 19 2
      modules/boonex/english/data/langs/system.xml
  5. 19 0
      modules/boonex/uni/data/template/studio/scripts/BxTemplStudioDashboard.php
  6. 0 3
      modules/boonex/uni/install/sql/disable.sql
  7. 0 3
      modules/boonex/uni/install/sql/enable.sql
  8. 14 21
      modules/boonex/uni/install/sql/install.sql
  9. 4 13
      modules/boonex/uni/install/sql/uninstall.sql
  10. 103 0
      studio/classes/BxDolStudioDashboard.php
  11. 1 1
      studio/classes/BxDolStudioDesign.php
  12. 16 0
      studio/classes/BxDolStudioDesigner.php
  13. 1 1
      studio/classes/BxDolStudioLanguage.php
  14. 1 1
      studio/classes/BxDolStudioModule.php
  15. 2 2
      studio/classes/BxDolStudioPage.php
  16. 1 1
      studio/classes/BxDolStudioUtils.php
  17. 36 0
      studio/dashboard.php
  18. 42 0
      studio/js/dashboard.js
  19. 23 0
      studio/js/designer.js
  20. 4 0
      studio/template/_header.html
  21. 25 0
      studio/template/css/dashboard.css
  22. 18 0
      studio/template/css/designer.css
  23. 0 26
      studio/template/css/general.css
  24. 3 0
      studio/template/css/page.css
  25. 27 3
      studio/template/css/page_columns.css
  26. 7 0
      studio/template/dashboard.html
  27. 11 0
      studio/template/dbd_space.html
  28. 18 0
      studio/template/dbd_versions.html
  29. BIN
      studio/template/images/dbd_version.png
  30. BIN
      studio/template/images/icons/mi-dsg-settings.png
  31. 0 0
      studio/template/images/icons/si-mod-empty.png
  32. 1 1
      studio/template/page_3.html
  33. 15 0
      studio/template/page_4.html
  34. 3 0
      studio/template/page_action_result.html
  35. 0 0
      studio/template/page_content_2_col.html
  36. 2 0
      studio/template/scripts/BxBaseStudioConfig.php
  37. 82 0
      studio/template/scripts/BxBaseStudioDashboard.php
  38. 52 7
      studio/template/scripts/BxBaseStudioDesigner.php
  39. 1 1
      studio/template/scripts/BxBaseStudioPage.php
  40. 5 5
      studio/template/scripts/BxBaseStudioStore.php
  41. 26 0
      studio/template/templates.html

+ 1 - 1
inc/classes/BxDolTemplate.php

@@ -485,7 +485,7 @@ class BxDolTemplate extends BxDol implements iBxDolSingleton {
         $this->_sCode = $oConfig->getUri();
         $this->_sSubPath = $oConfig->getDirectory();
 
-        if(!$bSetCookie)
+        if(!$bSetCookie || bx_get('preview'))
             return;
 
         $aUrl = parse_url(BX_DOL_URL_ROOT);

+ 10 - 3
inc/utils.inc.php

@@ -463,9 +463,16 @@ function sendMail($sRecipientEmail, $sMailSubject, $sMailBody, $iRecipientID = 0
 /*
  * Getting an array with Templates' Names
  */
-function get_templates_array($bEnabledOnly = true) {
-    bx_import('BxDolDb');
-    return BxDolDb::getInstance()->getPairs("SELECT `uri`, `title` FROM `sys_modules` WHERE 1 AND `type`='" . BX_DOL_MODULE_TYPE_TEMPLATE . "'" . ($bEnabledOnly ? " AND `enabled`='1'" : ""), "uri", "title");
+function get_templates_array($bEnabledOnly = true, $bShortInfo = true) {
+	bx_import('BxDolDb');
+	$oDb = BxDolDb::getInstance();
+
+	$sWhereAddon = $bEnabledOnly ? " AND `enabled`='1'" : "";
+	
+	if($bShortInfo)
+		return $oDb->getPairs("SELECT `uri`, `title` FROM `sys_modules` WHERE 1 AND `type`='" . BX_DOL_MODULE_TYPE_TEMPLATE . "'" . $sWhereAddon, "uri", "title");
+	else 
+		return $oDb->getAllWithKey("SELECT * FROM `sys_modules` WHERE 1 AND `type`='" . BX_DOL_MODULE_TYPE_TEMPLATE . "'" . $sWhereAddon, "uri"); 
 }
 
 /*

+ 5 - 1
install/sql/v70.sql

@@ -3414,6 +3414,10 @@ INSERT INTO `sys_std_pages`(`index`, `name`, `header`, `caption`, `icon`) VALUES
 (0, 'home', '_adm_page_cpt_home', '_adm_page_cpt_home', '');
 SET @iIdHome = LAST_INSERT_ID();
 
+INSERT INTO `sys_std_pages`(`index`, `name`, `header`, `caption`, `icon`) VALUES
+(4, 'dashboard', '_adm_page_cpt_dashboard', '_adm_page_cpt_dashboard', 'pi-dashboard.png');
+SET @iIdDashboard = LAST_INSERT_ID();
+
 INSERT INTO `sys_std_pages`(`index`, `name`, `header`, `caption`, `icon`) VALUES
 (3, 'settings', '_adm_page_cpt_settings', '_adm_page_cpt_settings', 'pi-settings.png');
 SET @iIdSettings = LAST_INSERT_ID();
@@ -3464,7 +3468,7 @@ INSERT INTO `sys_std_widgets`(`page_id`, `module`, `url`, `click`, `icon`, `capt
 INSERT INTO `sys_std_pages_widgets`(`page_id`, `widget_id`, `order`) VALUES(@iIdHome, LAST_INSERT_ID(), 2);
 
 INSERT INTO `sys_std_widgets`(`page_id`, `module`, `url`, `click`, `icon`, `caption`, `cnt_notices`, `cnt_actions`) VALUES
-(0, 'system', '{url_studio}dashboard.php', '', 'wi-dashboard.png', '_adm_wgt_cpt_dashboard', '435', '');
+(@iIdDashboard, 'system', '{url_studio}dashboard.php', '', 'wi-dashboard.png', '_adm_wgt_cpt_dashboard', '', '');
 INSERT INTO `sys_std_pages_widgets`(`page_id`, `widget_id`, `order`) VALUES(@iIdHome, LAST_INSERT_ID(), 3);
 
 

+ 19 - 2
modules/boonex/english/data/langs/system.xml

@@ -1574,7 +1574,6 @@ Please click "Continue" below to navigate to the home page of the site.]]></stri
 	<string name="_adm_reg_license"><![CDATA[License:]]></string>
 	<string name="_adm_reg_actions"><![CDATA[If money is tight, or you do not feel like supporting BoonEx, or just want to test-drive Dolphin you can <a href="http://www.boonex.com/websites/licenses/">generate a free license at BoonEx Unity</a> or <a href="{0}">continue using an unregistered copy</a>. In that case, links to BoonEx ads and promo blocks will remain on your site and admin panel.]]></string>
 	<string name="_adm_page_cpt_home"><![CDATA[Studio]]></string>
-	<string name="_adm_wgt_cpt_dashboard"><![CDATA[Dashboard]]></string>
 	<string name="_adm_wgt_cpt_community"><![CDATA[Community]]></string>
 	<string name="_adm_wgt_cpt_boonex"><![CDATA[BoonEx]]></string>
 	<string name="_adm_txt_module_system"><![CDATA[System]]></string>
@@ -1586,6 +1585,21 @@ Please click "Continue" below to navigate to the home page of the site.]]></stri
     <string name="_adm_txt_form_view_iu_delete"><![CDATA[Delete]]></string>
     <string name="_adm_err_form_view_iu_delete"><![CDATA[Cannot remove current image.]]></string>
     <string name="_adm_err_form_view_iu_save"><![CDATA[Cannot save: ]]></string>
+    <string name="_adm_err_cannot_process_action"><![CDATA[Cannot process action. It does not have an associated handler.]]></string>
+
+	<!-- Dashboard -->
+	<string name="_adm_wgt_cpt_dashboard"><![CDATA[Dashboard]]></string>
+	<string name="_adm_page_cpt_dashboard"><![CDATA[Dashboard]]></string>
+	<string name="_adm_block_cpt_versions"><![CDATA[Versions]]></string>
+	<string name="_adm_block_cpt_space"><![CDATA[Space Usage]]></string>
+	<string name="_adm_dbd_txt_dolphin_on"><![CDATA[Dolphin on]]></string>
+	<string name="_adm_dbd_txt_version"><![CDATA[Version:]]></string>
+	<string name="_adm_dbd_txt_installed"><![CDATA[Installed:]]></string>
+	<string name="_adm_dbd_txt_dolphin_n_available"><![CDATA[Dolphin {0} available!]]></string>
+	<string name="_adm_dbd_txt_space_size"><![CDATA[Total space used: ]]></string>
+	<string name="_adm_dbd_txt_db_size"><![CDATA[Database size: ]]></string>
+	<string name="_adm_dbd_txt_media_size"><![CDATA[User media files: ]]></string>
+	<string name="_adm_dbd_btn_update"><![CDATA[Update]]></string>
 
     <!-- Settings -->
 	<string name="_adm_wgt_cpt_settings"><![CDATA[Settings]]></string>
@@ -1805,6 +1819,10 @@ Please click "Continue" below to navigate to the home page of the site.]]></stri
 	<string name="_adm_wgt_cpt_designer"><![CDATA[Designer]]></string>
 	<string name="_adm_lmi_cpt_logo"><![CDATA[Logo]]></string>
 	<string name="_adm_lmi_cpt_icon"><![CDATA[Site Icon]]></string>
+	<string name="_adm_lmi_cpt_settings"><![CDATA[Settings]]></string>
+	<string name="_adm_dsg_txt_default"><![CDATA[default]]></string>
+	<string name="_adm_dsg_btn_make_default"><![CDATA[Make Default]]></string>
+	<string name="_adm_dsg_err_make_default"><![CDATA[Cannot make the template default.]]></string>
 	<string name="_adm_dsg_txt_upload_image"><![CDATA[Upload New Logo Image]]></string>
 	<string name="_adm_dsg_txt_upload_image_preview"><![CDATA[Current Logo Image]]></string>
 	<string name="_adm_dsg_txt_alt_text"><![CDATA[Logo Text]]></string>
@@ -2682,7 +2700,6 @@ Please click "Continue" below to navigate to the home page of the site.]]></stri
 	<string name="_adm_box_cpt_design_templates"><![CDATA[Design templates from Unity Market]]></string>
 	<string name="_adm_box_cpt_lang_files"><![CDATA[Language files from Unity Market]]></string>
 	<string name="_adm_page_cpt_login"><![CDATA[Login]]></string>
-	<string name="_adm_page_cpt_dashboard"><![CDATA[Dashboard]]></string>
 	<string name="_adm_page_cpt_lang_file"><![CDATA[Manage Languages]]></string>
 	<string name="_adm_page_cpt_memb_levels"><![CDATA[Manage Membership Levels]]></string>
 	<string name="_adm_page_cpt_email_templates"><![CDATA[Email Templates]]></string>

+ 19 - 0
modules/boonex/uni/data/template/studio/scripts/BxTemplStudioDashboard.php

@@ -0,0 +1,19 @@
+<?php
+/**
+ * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * CC-BY License - http://creativecommons.org/licenses/by/3.0/
+ *
+ * @defgroup    DolphinView Dolphin Studio Representation classes
+ * @ingroup     DolphinStudio
+ * @{
+ */
+defined('BX_DOL') or die('hack attempt');
+
+bx_import('BxBaseStudioDashboard');
+
+class BxTemplStudioDashboard extends BxBaseStudioDashboard { 
+    function __construct() {
+        parent::__construct();
+    }
+}
+/** @} */

+ 0 - 3
modules/boonex/uni/install/sql/disable.sql

@@ -1,4 +1 @@
---
--- General section.
---
 SET @sName = 'bx_uni';

+ 0 - 3
modules/boonex/uni/install/sql/enable.sql

@@ -1,4 +1 @@
---
--- General section.
---
 SET @sName = 'bx_uni';

+ 14 - 21
modules/boonex/uni/install/sql/install.sql

@@ -1,26 +1,6 @@
---
--- General section.
---
 SET @sName = 'bx_uni';
 
---
--- Studio page and widget.
---
-INSERT INTO `sys_std_pages`(`index`, `name`, `header`, `caption`, `icon`) VALUES
-(3, @sName, '', '', 'bx_uni@modules/boonex/uni/|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, @sName, CONCAT('{url_studio}design.php?name=', @sName), '', 'bx_uni@modules/boonex/uni/|std-wi.png', '_bx_uni_wgt_cpt', '', '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:"TemplStudioDesigns";}');
-INSERT INTO `sys_std_pages_widgets`(`page_id`, `widget_id`, `order`) VALUES
-(@iParentPageId, LAST_INSERT_ID(), @iParentPageOrder + 1);
-
-
---
--- Settings.
---
+-- SETTINGS
 INSERT INTO `sys_options_types`(`group`, `name`, `caption`, `icon`, `order`) VALUES 
 ('templates', @sName, '_bx_uni_stg_cpt_type', 'bx_uni@modules/boonex/uni/|std-mi.png', 2);
 SET @iTypeId = LAST_INSERT_ID();
@@ -31,3 +11,16 @@ SET @iCategoryId = LAST_INSERT_ID();
 
 INSERT INTO `sys_options`(`category_id`, `name`, `caption`, `value`, `type`, `extra`, `check`, `check_error`, `order`) VALUES
 (@iCategoryId, CONCAT(@sName, '_switcher_title'), 'Name In Template Switcher', 'UNI', 'digit', '', '', '', 1);
+
+
+-- STUDIO PAGE & WIDGET
+INSERT INTO `sys_std_pages`(`index`, `name`, `header`, `caption`, `icon`) VALUES
+(3, @sName, '', '', 'bx_uni@modules/boonex/uni/|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, @sName, CONCAT('{url_studio}design.php?name=', @sName), '', 'bx_uni@modules/boonex/uni/|std-wi.png', '_bx_uni_wgt_cpt', '', '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:"TemplStudioDesigns";}');
+INSERT INTO `sys_std_pages_widgets`(`page_id`, `widget_id`, `order`) VALUES
+(@iParentPageId, LAST_INSERT_ID(), @iParentPageOrder + 1);

+ 4 - 13
modules/boonex/uni/install/sql/uninstall.sql

@@ -1,18 +1,9 @@
---
--- General section.
---
 SET @sName = 'bx_uni';
 
+-- 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`=@sName;
 
---
--- Studio page and widget.
---
+-- STUDIO PAGE & 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`=@sName;
-
-
---
--- 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`=@sName;
+WHERE `tp`.`id` = `tw`.`page_id` AND `tw`.`id` = `tpw`.`widget_id` AND `tp`.`name` = @sName;

+ 103 - 0
studio/classes/BxDolStudioDashboard.php

@@ -0,0 +1,103 @@
+<?php
+/**
+ * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * CC-BY License - http://creativecommons.org/licenses/by/3.0/
+ *
+ * @defgroup    DolphinStudio Dolphin Studio
+ * @{
+ */
+defined('BX_DOL') or die('hack attempt');
+
+bx_import('BxTemplStudioPage');
+bx_import('BxDolStudioStoreQuery');
+
+class BxDolStudioDashboard extends BxTemplStudioPage {
+	function __construct() {
+        parent::BxTemplStudioPage('dashboard');
+
+		//--- Check actions ---//
+        if(($sAction = bx_get('dbd_action')) !== false) {
+	        $sAction = bx_process_input($sAction);
+
+            $aResult = array('code' => 1, 'message' => _t('_adm_err_cannot_process_action'));
+	        switch($sAction) {
+	        	case 'check_update_script':
+	        		$aResult = array();
+
+	        		$sContent = bx_file_get_contents(BX_DOL_URL_ROOT . 'get_rss_feed.php?ID=boonex_version&member=0');
+	        		if(empty($sContent))
+	        			break;
+
+	        		bx_import('BxDolXmlParser');
+	        		$aContent = BxDolXmlParser::getInstance()->getTags($sContent, 'dolphin', 0);
+	        		if(empty($aContent) || !is_array($aContent) || empty($aContent['value']))
+	        			break;
+
+	        		$sVersionAvl = $aContent['value'];
+	        		$sVersionCur = BxDolDb::getInstance()->getParam('sys_version');
+	        		if(version_compare($sVersionCur, $sVersionAvl) == -1)
+			        	$aResult = array('version' => $sVersionAvl);
+			    	break;
+	        	/*
+	        	case 'action_name':
+			        $aResult = array();
+			    	break;
+			    */
+	        }
+
+	        if(!empty($aResult['message'])) {
+                bx_import('BxDolStudioTemplate');
+                $aResult['message'] = BxDolStudioTemplate::getInstance()->parseHtmlByName('page_action_result.html', array('content' => $aResult['message']));
+
+                bx_import('BxTemplStudioFunctions');
+                $aResult['message'] = BxTemplStudioFunctions::getInstance()->transBox('', $aResult['message']);
+            }
+
+	        $oJson = new Services_JSON();		        
+            echo $oJson->encode($aResult);
+            exit;
+        }
+    }
+
+    protected function loadBlocks() {
+        $aNames = array('versions', 'space');  	
+
+        $aBlocks = array();
+        foreach($aNames as $sName)
+	        $aBlocks[$sName] = array(
+	            'caption' => '_adm_block_cpt_' . $sName,
+	            'actions' => array(), 
+	            'items' => ''
+	        );
+
+        return $aBlocks;
+    }
+
+    protected function getDbSize() {
+    	$iTotalSize = 0;
+    	$oDb = BxDolDb::getInstance();
+
+    	$aTables = $oDb->getAll('SHOW TABLE STATUS');
+    	foreach($aTables as $aTable)
+    		$iTotalSize += $aTable['Data_length'] + $aTable['Index_length'];
+
+		return $iTotalSize;
+    }
+
+	protected function getFolderSize($sPath) {
+		$iTotalSize = 0;
+		$aFiles = scandir($sPath);
+
+		$sPath = rtrim($sPath, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
+		foreach($aFiles as $sFile) {
+			if(is_dir($sPath . $sFile))
+      			if($sFile != '.' && $sFile != '..')
+          			$iTotalSize += $this->getFolderSize($sPath . $sFile); 
+	    	else
+	      		$iTotalSize += filesize($sPath . $sFile);
+		}
+
+		return $iTotalSize;
+	}
+}
+/** @} */

+ 1 - 1
studio/classes/BxDolStudioDesign.php

@@ -96,7 +96,7 @@ class BxDolStudioDesign extends BxTemplStudioPage {
 
         $aResult = array('code' => 0, 'message' => _t('_adm_scs_operation_done'));
         if((int)$aTemplate['enabled'] == 0) {
-            $aResult['content'] = $oTemplate->parseHtmlByName('page_content.html', array(
+            $aResult['content'] = $oTemplate->parseHtmlByName('page_content_2_col.html', array(
                 'page_menu_code' => $this->getPageMenu(),
                 'page_main_code' => $this->getPageCode()
             ));

+ 16 - 0
studio/classes/BxDolStudioDesigner.php

@@ -14,6 +14,7 @@ bx_import('BxDolStudioDesignerQuery');
 define('BX_DOL_STUDIO_DSG_TYPE_GENERAL', 'general');
 define('BX_DOL_STUDIO_DSG_TYPE_LOGO', 'logo');
 define('BX_DOL_STUDIO_DSG_TYPE_ICON', 'icon');
+define('BX_DOL_STUDIO_DSG_TYPE_SETTINGS', 'settings');
 
 define('BX_DOL_STUDIO_DSG_TYPE_DEFAULT', 'general');
 
@@ -39,6 +40,12 @@ class BxDolStudioDesigner extends BxTemplStudioPage {
 	                $aResult = array('code' => 0, 'message' => '');
                     if(!$this->deleteLogo())
                         $aResult = array('code' => 2, 'message' => _t('_adm_dsg_err_remove_old_logo'));
+	                break;
+
+				case 'make_default':
+	                $aResult = array('code' => 0, 'message' => '');
+                    if(!$this->makeDefault())
+                        $aResult = array('code' => 2, 'message' => _t('_adm_dsg_err_make_default'));
 	                break;
 
 	            case 'get-page-by-type':
@@ -57,6 +64,15 @@ class BxDolStudioDesigner extends BxTemplStudioPage {
         }
     }
 
+    function makeDefault() {
+    	$sValue = bx_get('dsg_value');
+    	if($sValue === false)
+    		return false;
+
+    	$sValue = bx_process_input($sValue);
+    	return $this->oDb->setParam('template', $sValue);
+    }
+
     function submitLogo(&$oForm) {
         $iProfileId = getLoggedId();
 

+ 1 - 1
studio/classes/BxDolStudioLanguage.php

@@ -95,7 +95,7 @@ class BxDolStudioLanguage extends BxTemplStudioPage {
 
         $aResult = array('code' => 0, 'message' => _t('_adm_scs_operation_done'));
         if((int)$aLanguage['enabled'] == 0) {
-            $aResult['content'] = $oTemplate->parseHtmlByName('page_content.html', array(
+            $aResult['content'] = $oTemplate->parseHtmlByName('page_content_2_col.html', array(
                 'page_menu_code' => $this->getPageMenu(),
                 'page_main_code' => $this->getPageCode()
             ));

+ 1 - 1
studio/classes/BxDolStudioModule.php

@@ -83,7 +83,7 @@ class BxDolStudioModule extends BxTemplStudioPage {
 
         $aResult = array('code' => 0, 'message' => _t('_adm_scs_operation_done'));
         if((int)$aModule['enabled'] == 0) {
-            $aResult['content'] = $oTemplate->parseHtmlByName('page_content.html', array(
+            $aResult['content'] = $oTemplate->parseHtmlByName('page_content_2_col.html', array(
                 'page_menu_code' => $this->getPageMenu(),
                 'page_main_code' => $this->getPageCode()
             ));

+ 2 - 2
studio/classes/BxDolStudioPage.php

@@ -113,8 +113,8 @@ class BxDolStudioPage extends BxDol {
         return BxDolStudioUtils::getModuleTitle($sName);
     }
 
-    protected function getModuleIcon($sName) {
-        return BxDolStudioUtils::getModuleIcon($sName);
+    protected function getModuleIcon($sName, $sType = 'menu') {
+        return BxDolStudioUtils::getModuleIcon($sName, $sType);
     }
     
     protected function getModules($bShowCustom = true, $bShowSystem = true) {

+ 1 - 1
studio/classes/BxDolStudioUtils.php

@@ -30,7 +30,7 @@ class BxDolStudioUtils extends BxDol {
     }
 
     public static function getModuleIcon($sName, $sType = 'menu') {
-        $aType2Prefix = array('menu' => 'mi', 'page' => 'pi');
+        $aType2Prefix = array('menu' => 'mi', 'page' => 'pi', 'store' => 'si');
 
         $oTemplate = BxDolStudioTemplate::getInstance();
         $sDefaultIcon = $oTemplate->getIconUrl($aType2Prefix[$sType] . '-mod-empty.png'); 

+ 36 - 0
studio/dashboard.php

@@ -0,0 +1,36 @@
+<?php
+/**
+ * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * CC-BY License - http://creativecommons.org/licenses/by/3.0/
+ *
+ * @defgroup    DolphinEndAdmin Dolphin Studio End Admin Pages 
+ * @ingroup     DolphinStudio
+ * @{
+ */
+
+require_once('./../inc/header.inc.php');
+require_once(BX_DOL_DIR_STUDIO_INC . 'utils.inc.php');
+
+require_once(BX_DIRECTORY_PATH_INC . 'params.inc.php');
+require_once(BX_DIRECTORY_PATH_INC . 'design.inc.php');
+require_once(BX_DIRECTORY_PATH_PLUGINS . 'Services_JSON.php');
+
+bx_import('BxDolLanguages');
+
+bx_require_authentication(true);
+
+bx_import('BxTemplStudioDashboard');
+$oPage = new BxTemplStudioDashboard();
+
+bx_import('BxDolStudioTemplate');
+$oTemplate = BxDolStudioTemplate::getInstance();
+$oTemplate->setPageNameIndex($oPage->getPageIndex());
+$oTemplate->setPageHeader($oPage->getPageHeader());
+$oTemplate->setPageContent('page_caption_code', $oPage->getPageCaption());
+$oTemplate->setPageContent('page_attributes', $oPage->getPageAttributes());
+//$oTemplate->setPageContent('page_menu_code', $oPage->getPageMenu());
+$oTemplate->setPageContent('page_main_code', $oPage->getPageCode());
+$oTemplate->addCss($oPage->getPageCss());
+$oTemplate->addJs($oPage->getPageJs());
+$oTemplate->getPageCode();
+/** @} */

+ 42 - 0
studio/js/dashboard.js

@@ -0,0 +1,42 @@
+/**
+ * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * CC-BY License - http://creativecommons.org/licenses/by/3.0/
+ *
+ * @defgroup    DolphinStudio Dolphin Studio
+ * @{
+ */
+function BxDolStudioDashboard(oOptions) {
+	this.sActionsUrl = oOptions.sActionUrl;
+    this.sObjName = oOptions.sObjName == undefined ? 'oBxDolStudioDashboard' : oOptions.sObjName;
+    this.sAnimationEffect = oOptions.sAnimationEffect == undefined ? 'fade' : oOptions.sAnimationEffect;
+    this.iAnimationSpeed = oOptions.iAnimationSpeed == undefined ? 'slow' : oOptions.iAnimationSpeed;
+
+    var $this = this;
+    $(document).ready(function() {
+    	$('.bx-dbd-block-content').bxTime();
+
+    	$this.checkForUpdateScript();
+    });
+}
+
+BxDolStudioDashboard.prototype.checkForUpdateScript = function() {
+	var $this = this;
+	var oDate = new Date();
+	var sDivId = 'bx-dbd-update-script';
+
+	$.get(
+		this.sActionsUrl,
+		{
+			dbd_action: 'check_update_script',
+			_t: oDate.getTime()
+		},
+		function(oData) {
+			if(!oData.version)
+			    return;
+
+			$('#' + sDivId + ' span').html(_t('_adm_dbd_txt_dolphin_n_available', oData.version)).parents('#' + sDivId + ':hidden').show();
+		},
+		'json'
+	);
+};
+/** @} */

+ 23 - 0
studio/js/designer.js

@@ -12,6 +12,29 @@ function BxDolStudioDesigner(oOptions) {
     this.iAnimationSpeed = oOptions.iAnimationSpeed == undefined ? 'slow' : oOptions.iAnimationSpeed;
 }
 
+BxDolStudioDesigner.prototype.makeDefault = function(sUri) {
+	var $this = this;
+	var oDate = new Date();
+
+	$.post(
+		this.sActionsUrl,
+		{
+			dsg_action: 'make_default',
+			dsg_value: sUri,
+			_t: oDate.getTime()
+		},
+		function(oData) {
+			if(oData.code != 0 && oData.message.length > 0) {
+				alert(oData.message);
+				return;
+			}
+
+			document.location.href = document.location.href; 
+		},
+		'json'
+	);
+};
+
 BxDolStudioDesigner.prototype.deleteLogo = function() {
 	var $this = this;
 	var oDate = new Date();

+ 4 - 0
studio/template/_header.html

@@ -45,6 +45,10 @@
                 top: 'auto',
                 left: 'auto'
             }); 
+
+			$(document).ready(function () {
+				bx_time('__lang__');
+			});
         </script>
         __extra_js__
 

+ 25 - 0
studio/template/css/dashboard.css

@@ -0,0 +1,25 @@
+div.bx-dbd-block-content {
+	position: relative;
+}
+
+/*--- Versions block ---*/
+div.bx-dbd-virsion-image {
+	position: absolute;
+	top: 0px;
+	left: 0px;
+}
+div.bx-dbd-virsion-info {
+	position: relative;
+	min-height: 110px;
+	margin-left: 120px;
+}
+div.bx-dbd-vi-column {
+	position: relative;
+	float: left;
+	width: 50%;
+}
+div.bx-dbd-update-script span {
+	line-height: 26px;
+	line-height: 1.6rem;
+}
+/*--- Space Usage block ---*/

+ 18 - 0
studio/template/css/designer.css

@@ -0,0 +1,18 @@
+/*--- Template Switcher ---*/
+div.bx-dsg-template {
+	position: relative;
+	width: 100%;
+}
+
+div.bx-dsg-icon {
+	position: absolute;
+	top: 0px;
+	left: 0px;
+	overflow: hidden;
+}
+div.bx-dsg-template-info {
+	overflow: hidden;
+}
+span.bx-dsg-template-version {
+	font-weight: bold;
+}

+ 0 - 26
studio/template/css/general.css

@@ -94,32 +94,6 @@ div.bx-std-pcap-mp-right div.bx-std-pcap-action {
     float: right;
 }
 
-div.bx-std-page-columns {
-	position: relative;
-	overflow: hidden;
-}
-div.bx-std-page-columns-cnt {
-	width: 200%;
-}
-div.bx-std-page-column-wrp {
-	position: relative;
-	float: right;
-	width: 50%;
-}
-div.bx-std-page-column {}
-div.bx-std-page-column-cnt {}
-div.bx-std-page-menu {
-	position: relative;
-	float: left;
-    width: 230px;
-}
-div.bx-std-page-content {
-	position: relative;
-	right: 100%;
-	margin-left: 230px;
-}
-
-
 /**
  * Page Menu (Left Side)
  */

+ 3 - 0
studio/template/css/page.css

@@ -0,0 +1,3 @@
+body.bx-std-bg {
+	background-color: #ffffff;
+}

+ 27 - 3
studio/template/css/page_columns.css

@@ -1,6 +1,4 @@
-body.bx-std-bg {
-	background-color: #ffffff;
-}
+/*--- Background ---*/
 div.bx-std-page-bg {
 	background-image: url(../images/bx-std-bg-columns.png);
 	background-repeat: repeat-y;
@@ -8,4 +6,30 @@ div.bx-std-page-bg {
 }
 div.bx-std-page-bg-empty {
     background-image: url(../images/bx-std-spacer.gif);
+}
+
+/*--- 2 columns ---*/
+div.bx-std-page-columns {
+	position: relative;
+	overflow: hidden;
+}
+div.bx-std-page-columns-cnt {
+	width: 200%;
+}
+div.bx-std-page-column-wrp {
+	position: relative;
+	float: right;
+	width: 50%;
+}
+div.bx-std-page-column {}
+div.bx-std-page-column-cnt {}
+div.bx-std-page-menu {
+	position: relative;
+	float: left;
+    width: 230px;
+}
+div.bx-std-page-content {
+	position: relative;
+	right: 100%;
+	margin-left: 230px;
 }

+ 7 - 0
studio/template/dashboard.html

@@ -0,0 +1,7 @@
+<script defer type="text/javascript">
+    var __js_object__ = new BxDolStudioDashboard({
+        sActionUrl: '<bx_url_studio />dashboard.php',
+        sVersion: '__version__'
+    });
+</script>
+<bx_include_auto:page_blocks.html />

+ 11 - 0
studio/template/dbd_space.html

@@ -0,0 +1,11 @@
+<div class="bx-dbd-block-content bx-def-margin-bottom">
+	<div class="bx-def-margin-thd-top-auto">
+		<span><bx_text:_adm_dbd_txt_space_size />&nbsp;</span><b>__space_size__</b>
+	</div>
+	<div class="bx-def-margin-thd-top-auto">
+		<span><bx_text:_adm_dbd_txt_db_size />&nbsp;</span><b>__db_size__</b>
+	</div>
+	<div class="bx-def-margin-thd-top-auto">
+		<span><bx_text:_adm_dbd_txt_media_size />&nbsp;</span><b>__media_size__</b>
+	</div>
+</div>

+ 18 - 0
studio/template/dbd_versions.html

@@ -0,0 +1,18 @@
+<div class="bx-dbd-block-content bx-def-margin-bottom">
+	<div class="bx-dbd-virsion-image">
+		<img src="<bx_image_url:dbd_version.png />"/>
+	</div>
+	<div class="bx-dbd-virsion-info bx-clearfix">
+		<div class="bx-dbd-vi-column">
+			<div class="bx-def-margin-thd-top"><bx_text:_adm_dbd_txt_dolphin_on />&nbsp;<b>__domain__</b></div>
+			<div class="bx-def-margin-thd-top"><bx_text:_adm_dbd_txt_version />&nbsp;<b>__version__</b>&nbsp;<bx_text:_adm_dbd_txt_installed />&nbsp;<b>__installed__</b></div>
+			<div class="bx-dbd-update-script bx-def-margin-thd-top" id="bx-dbd-update-script" style="display:none">
+				<a class="bx-btn bx-btn-small" href="javascript:void(0)" onclick="javascript:alert('TODO: Redirect to update script.')"><bx_text:_adm_dbd_btn_update /></a>
+				<span class="col-red1 bx-def-padding-thd-left"></span>
+			</div>
+		</div>
+		<div class="bx-dbd-vi-column">
+			Modules updated would be here.
+		</div>
+	</div>
+</div>

BIN
studio/template/images/dbd_version.png


BIN
studio/template/images/icons/mi-dsg-settings.png


+ 0 - 0
studio/template/images/icons/pi-str-dump.png → studio/template/images/icons/si-mod-empty.png


+ 1 - 1
studio/template/page_3.html

@@ -9,7 +9,7 @@
     </script>
     <div class="bx-std-page-caption">__page_caption_code__</div>
     <div class="bx-std-page-columns" id="bx-std-page-columns" __page_attributes__>
-        <bx_include_auto:page_content.html />
+        <bx_include_auto:page_content_2_col.html />
     </div>
 </div>
 <bx_include_auto:_sub_footer.html />

+ 15 - 0
studio/template/page_4.html

@@ -0,0 +1,15 @@
+<bx_include_auto:_sub_header.html />
+<div class="bx-std-content-wrp">
+    <script defer type="text/javascript">
+    <!--
+    var oBxDolStudioPage = new BxDolStudioPage({
+        sActionUrl: '<bx_url_studio />ajax.php'
+    });
+    -->
+    </script>
+    <div class="bx-std-page-caption">__page_caption_code__</div>
+    <div class="bx-std-page-content" id="bx-std-page-content" __page_attributes__>
+    	<div class="bx-std-page-content-cnt bx-def-padding">__page_main_code__</div>
+    </div>
+</div>
+<bx_include_auto:_sub_footer.html />

+ 3 - 0
studio/template/page_action_result.html

@@ -0,0 +1,3 @@
+<div class="bx-std-action-result bx-def-popup-width bx-def-color-bg-block">
+    <div class="bx-std-action-result-cnt bx-def-padding">__content__</div>
+</div>

+ 0 - 0
studio/template/page_content.html → studio/template/page_content_2_col.html


+ 2 - 0
studio/template/scripts/BxBaseStudioConfig.php

@@ -7,6 +7,8 @@
  * @{
  */
 
+bx_import('BxTemplConfig');
+
 class BxBaseStudioConfig extends BxTemplConfig {
 
     function __construct() 

+ 82 - 0
studio/template/scripts/BxBaseStudioDashboard.php

@@ -0,0 +1,82 @@
+<?php
+/**
+ * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * CC-BY License - http://creativecommons.org/licenses/by/3.0/
+ *
+ * @defgroup    DolphinView Dolphin Studio Representation classes
+ * @ingroup     DolphinStudio
+ * @{
+ */
+defined('BX_DOL') or die('hack attempt');
+
+bx_import('BxDolStudioDashboard');
+
+class BxBaseStudioDashboard extends BxDolStudioDashboard {
+    function __construct() {
+        parent::__construct();
+    }
+
+    function getPageCss() {
+        return array_merge(parent::getPageCss(), array('dashboard.css'));
+    }
+
+    function getPageJs() {
+        return array_merge(parent::getPageJs(), array('dashboard.js'));
+    }
+
+    function getPageJsObject() {
+        return 'oBxDolStudioDashboard';
+    }
+
+    function getPageCode($bHidden = false) {
+        $oTemplate = BxDolStudioTemplate::getInstance();
+
+        $aBlocks = $this->loadBlocks();
+
+        $aTmplVars = array(
+			'js_object' => $this->getPageJsObject(),
+            'bx_repeat:blocks' => array()
+        );
+
+        $sActions = "";
+        foreach($aBlocks as $sName => $aBlock) {
+        	$sMethod = 'getBlockCode' . ucfirst($sName);
+        	if(!method_exists($this, $sMethod))
+        		continue;
+
+            $aTmplVars['bx_repeat:blocks'][] = array(
+            	'caption' => $this->getBlockCaption($aBlock),
+                'items' => $this->$sMethod($sName, $aBlock)
+            );
+        }
+
+        return $oTemplate->parseHtmlByName('dashboard.html', $aTmplVars);
+    }
+
+    protected function getBlockCodeVersions($sName, $aBlock)
+    {
+    	$oDb = BxDolDb::getInstance();
+    	$oTemplate = BxDolStudioTemplate::getInstance();
+
+    	$oTemplate->addJsTranslation('_adm_dbd_txt_dolphin_n_available');
+    	return $oTemplate->parseHtmlByName('dbd_versions.html', array(
+    		'domain' => $oDb->getParam('site_title'),
+    		'version' => $oDb->getParam('sys_version'),
+    		'installed' => bx_time_js(time()-1000)
+    	));
+    }
+
+	protected function getBlockCodeSpace($sName, $aBlock)
+    {
+    	$sSizesSpace = $this->getFolderSize(BX_DIRECTORY_PATH_ROOT);
+    	$iSizeDb = $this->getDbSize();
+		$sSizesMedia = $this->getFolderSize(BX_DIRECTORY_STORAGE);
+
+    	return BxDolStudioTemplate::getInstance()->parseHtmlByName('dbd_space.html', array(
+    		'space_size' => _t_format_size($sSizesSpace),
+    		'db_size' => _t_format_size($iSizeDb),
+    		'media_size' => _t_format_size($sSizesMedia)
+    	));
+    }
+}
+/** @} */

+ 52 - 7
studio/template/scripts/BxBaseStudioDesigner.php

@@ -36,9 +36,10 @@ class BxBaseStudioDesigner extends BxDolStudioDesigner {
 
         $aMenu = array();
         $aMenuItems = array(
-            BX_DOL_STUDIO_DSG_TYPE_GENERAL, 
-            BX_DOL_STUDIO_DSG_TYPE_LOGO, 
-            BX_DOL_STUDIO_DSG_TYPE_ICON
+            BX_DOL_STUDIO_DSG_TYPE_GENERAL,
+            BX_DOL_STUDIO_DSG_TYPE_LOGO,
+            BX_DOL_STUDIO_DSG_TYPE_ICON,
+            BX_DOL_STUDIO_DSG_TYPE_SETTINGS
         );
         foreach($aMenuItems as $sMenuItem)
             $aMenu[] = array(
@@ -60,14 +61,44 @@ class BxBaseStudioDesigner extends BxDolStudioDesigner {
     }
 
     protected function getGeneral() {
+    	$sJsObject = $this->getPageJsObject();
         $oTemplate = BxDolStudioTemplate::getInstance();
-        
-        bx_import('BxTemplStudioSettings');
-        $oPage = new BxTemplStudioSettings(BX_DOL_STUDIO_STG_TYPE_SYSTEM, BX_DOL_STUDIO_STG_CATEGORY_TEMPLATES);
+
+        $sResult = '';
+
+        $sTemplate = getParam('template');
+        $aTemplates = get_templates_array(true, false);        
+
+	    $aTmplVarsTemplates = array ();
+	    foreach($aTemplates as $sUri => $aTemplate) {
+	        $aTmplVarsTemplates[] = array(
+	            'uri' => $sUri,
+	            'title' => htmlspecialchars_adv($aTemplate['title']),
+	            'version' => htmlspecialchars_adv($aTemplate['version']),
+	            'vendor' => htmlspecialchars_adv($aTemplate['vendor']),
+	        	'icon' => $this->getModuleIcon($aTemplate['name'], 'store'),
+	            'bx_if:default' => array (
+	                'condition' => $sUri == $sTemplate,
+	                'content' => array (),
+	            ),
+	            'bx_if:make_default' => array (
+	                'condition' => $sUri != $sTemplate,
+	                'content' => array(
+	            		'js_object' => $sJsObject,
+	                	'uri' => $sUri
+	            	),
+	            )
+	        );
+	    }
+
+	    $sContent  = $sResult ? MsgBox($sResult, 10) : '';
+	    $sContent .= $oTemplate->parseHtmlByName('templates.html', array(
+	        'bx_repeat:templates' => $aTmplVarsTemplates,
+	    ));
 
         $aTmplVars = array(
             'js_object' => $this->getPageJsObject(),
-        	'bx_repeat:blocks' => $oPage->getPageCode(),
+        	'bx_repeat:blocks' => $sContent,
         );
 
         return $oTemplate->parseHtmlByName('designer.html', $aTmplVars);
@@ -250,6 +281,20 @@ class BxBaseStudioDesigner extends BxDolStudioDesigner {
             )
         );
 
+        return $oTemplate->parseHtmlByName('designer.html', $aTmplVars);
+    }
+
+	protected function getSettings() {
+        $oTemplate = BxDolStudioTemplate::getInstance();
+        
+        bx_import('BxTemplStudioSettings');
+        $oPage = new BxTemplStudioSettings(BX_DOL_STUDIO_STG_TYPE_SYSTEM, BX_DOL_STUDIO_STG_CATEGORY_TEMPLATES);
+
+        $aTmplVars = array(
+            'js_object' => $this->getPageJsObject(),
+        	'bx_repeat:blocks' => $oPage->getPageCode(),
+        );
+
         return $oTemplate->parseHtmlByName('designer.html', $aTmplVars);
     }
 }

+ 1 - 1
studio/template/scripts/BxBaseStudioPage.php

@@ -63,7 +63,7 @@ class BxBaseStudioPage extends BxDolStudioPage {
     }
 
     function getPageCss() {
-        $aCss = array('menu_top.css');
+        $aCss = array('page.css', 'menu_top.css');
         if((int)$this->aPage['index'] == 3)
             $aCss[] = 'page_columns.css';
 

+ 5 - 5
studio/template/scripts/BxBaseStudioStore.php

@@ -292,9 +292,9 @@ class BxBaseStudioStore extends BxDolStudioStore {
 
 		//--- Prepare modules.
         foreach($aProducts['modules'] as $aModule) {
-            $sIcon = $oTemplate->getIconUrl($aModule['name'] . '@modules/' . $aModule['dir'] . '|std-si.png');
+        	$sIcon = $oTemplate->getIconUrl($aModule['name'] . '@modules/' . $aModule['dir'] . '|std-si.png');
             if(empty($sIcon))
-                $sIcon = $oTemplate->getIconUrl('pi-str-dump.png');
+                $sIcon = $oTemplate->getIconUrl('si-mod-empty.png');
 
             $sModules .= $oTemplate->parseHtmlByName('str_product_v1.html', array(
             	'js_object' => $sJsObject,
@@ -319,7 +319,7 @@ class BxBaseStudioStore extends BxDolStudioStore {
         foreach($aProducts['updates'] as $aUpdate) {
             $sIcon = $oTemplate->getIconUrl($aUpdate['module_name'] . '@modules/' . $aUpdate['module_dir'] . '|std-si.png');
             if(empty($sIcon))
-                $sIcon = $oTemplate->getIconUrl('pi-str-dump.png');
+                $sIcon = $oTemplate->getIconUrl('si-mod-empty.png');
 
             $sUpdates .= $oTemplate->parseHtmlByName('str_update_v1.html', array(
             	'js_object' => $sJsObject,
@@ -500,7 +500,7 @@ class BxBaseStudioStore extends BxDolStudioStore {
         		'js_object' => $sJsObject,
         		'id' => $aItem['id'],
 	            'url' => $aItem['url'],
-	            'icon' => !empty($aItem['thumbnail']['big']) ? $aItem['thumbnail']['big'] : $oTemplate->getIconUrl('pi-str-dump.png'),
+	            'icon' => !empty($aItem['thumbnail']['big']) ? $aItem['thumbnail']['big'] : $oTemplate->getIconUrl('si-mod-empty.png'),
 	            'title' => $aItem['title'],
         		'bx_if:show_vendor_price' => array(
         			'condition' => !$bShoppingCart,
@@ -563,7 +563,7 @@ class BxBaseStudioStore extends BxDolStudioStore {
         		'js_object' => $sJsObject,
         		'id' => $aItem['id'],
 	            'url' => $aItem['url'],
-	            'icon' => !empty($aItem['thumbnail']['big']) ? $aItem['thumbnail']['big'] : $oTemplate->getIconUrl('pi-str-dump.png'),
+	            'icon' => !empty($aItem['thumbnail']['big']) ? $aItem['thumbnail']['big'] : $oTemplate->getIconUrl('si-mod-empty.png'),
 	            'title' => $aItem['title'],
 	            'vendor' => $aItem['author'],
         		'versions' => _t('_adm_str_txt_update_from_to', $aItem['file_version'], $aItem['file_version_to']),

+ 26 - 0
studio/template/templates.html

@@ -0,0 +1,26 @@
+<div class="bx-dsg-templates">
+    <bx_repeat:templates>
+        <div class="bx-def-hr-auto bx-def-margin-top bx-def-margin-bottom"></div>
+        <div class="bx-dsg-template">
+            <div class="bx-dsg-icon bx-def-widget-size bx-def-round-corners-widget">
+				<img class="bx-def-widget-size" src="__icon__" />
+            </div>
+            <div class="bx-dsg-template-info bx-def-widget-size-min-height bx-def-widget-size-left-indent">
+                <div class="bx-dsg-template-title bx-def-margin-sec-top">
+                    <span class="bx-def-font-large">__title__</span>
+                    <bx_if:default>
+                        (<bx_text:_adm_dsg_txt_default />)
+                    </bx_if:default>
+                </div>
+                <div class="bx-dsg-template-subinfo bx-def-margin-thd-top bx-def-font-small">__vendor__ &bull; <span class="bx-dsg-template-version">__version__</span></div>
+                <div class="bx-dsg-template-actions bx-def-margin-thd-top">
+                    <bx_if:make_default>
+                        <a class="bx-btn bx-btn-small bx-def-margin-sec-left-auto" href="javascript:void(0)" onclick="javascript:__js_object__.makeDefault('__uri__')"><bx_text:_adm_dsg_btn_make_default /></a>
+                    </bx_if:make_default>
+                    <a class="bx-btn bx-btn-small bx-def-margin-sec-left-auto" href="<bx_url_root />?skin=__uri__&preview=1" target="_blank"><bx_text:_Preview /></a>
+                </div>
+            </div>
+            <div class="clear_both"></div>
+        </div>
+    </bx_repeat:templates>
+</div>