Browse Source

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

Conflicts:
	install/sql/system.sql
Alex Trofimov 12 năm trước cách đây
mục cha
commit
48c7cc4655
38 tập tin đã thay đổi với 455 bổ sung và 166 xóa
  1. 11 4
      inc/classes/BxDolAlerts.php
  2. 1 1
      inc/classes/BxDolCron.php
  3. 2 2
      inc/classes/BxDolImageTranscoder.php
  4. 10 5
      inc/classes/BxDolImageTranscoderQuery.php
  5. 22 25
      install/sql/system.sql
  6. 2 2
      modules/boonex/antispam/install/sql/enable.sql
  7. 1 1
      modules/boonex/convos/install/sql/enable.sql
  8. 10 0
      modules/boonex/developer/classes/BxDevFunctions.php
  9. 4 0
      modules/boonex/english/data/langs/system.xml
  10. 1 1
      modules/boonex/organizations/install/sql/enable.sql
  11. 1 1
      modules/boonex/persons/install/sql/enable.sql
  12. 1 1
      modules/boonex/profiler/install/sql/enable.sql
  13. 4 0
      modules/boonex/russian/data/langs/system.xml
  14. 0 28
      modules/boonex/sites/classes/BxSitesModule.php
  15. 64 0
      modules/boonex/sites/classes/BxSitesResponse.php
  16. 2 2
      modules/boonex/sites/install/sql/enable.sql
  17. 22 0
      modules/boonex/timeline/classes/BxTimelineFormCheckerHelper.php
  18. 6 7
      modules/boonex/timeline/classes/BxTimelineModule.php
  19. 3 2
      modules/boonex/timeline/classes/BxTimelineResponse.php
  20. 1 0
      modules/boonex/timeline/install/langs/en.xml
  21. 9 9
      modules/boonex/timeline/install/sql/enable.sql
  22. 21 0
      modules/boonex/uni/data/template/system/scripts/BxTemplAclServices.php
  23. 1 1
      modules/boonex/uni/data/template/system/scripts/BxTemplCmtsServices.php
  24. 21 0
      modules/boonex/uni/data/template/system/scripts/BxTemplImageServices.php
  25. 21 0
      modules/boonex/uni/data/template/system/scripts/BxTemplLanguagesServices.php
  26. 21 0
      modules/boonex/uni/data/template/system/scripts/BxTemplTemplateServices.php
  27. 2 4
      periodic/cron.php
  28. 8 2
      studio/classes/BxDolStudioForm.php
  29. 23 49
      studio/classes/BxDolStudioInstaller.php
  30. 18 4
      studio/classes/BxDolStudioSettings.php
  31. 7 1
      studio/classes/BxDolStudioSettingsQuery.php
  32. 1 1
      studio/template/css/dashboard.css
  33. 11 9
      studio/template/scripts/BxBaseStudioNavigationMenus.php
  34. 0 4
      studio/template/scripts/BxBaseStudioSettings.php
  35. 25 0
      template/scripts/BxBaseAclServices.php
  36. 32 0
      template/scripts/BxBaseImageServices.php
  37. 33 0
      template/scripts/BxBaseLanguagesServices.php
  38. 33 0
      template/scripts/BxBaseTemplateServices.php

+ 11 - 4
inc/classes/BxDolAlerts.php

@@ -95,8 +95,15 @@ class BxDolAlerts extends BxDol {
 
                     $oHandler = new $aHandler['class']();
                     $oHandler->response($this);
-                } else if (!empty($aHandler['eval'])) {
-                    eval($aHandler['eval']);
+                } 
+                else if(!empty($aHandler['service_call']) && BxDolService::isSerializedService($aHandler['service_call'])) {
+                	$aService = unserialize($aHandler['service_call']);
+
+                	$aParams = array($this);
+                	if(isset($aService['params']) && is_array($aService['params']))
+                		$aParams = array_merge($aParams, $aService['params']);
+
+					BxDolService::call($aService['module'], $aService['method'], $aParams, isset($aService['class']) ? $aService['class'] : 'Module');
                 }
             }
     }
@@ -114,9 +121,9 @@ class BxDolAlerts extends BxDol {
         foreach ($aAlerts as $aAlert)
             $aResult['alerts'][$aAlert['unit']][$aAlert['action']][] = $aAlert['handler_id'];
 
-        $aHandlers = $oDb->getAll("SELECT `id`, `class`, `file`, `eval` FROM `sys_alerts_handlers` ORDER BY `id` ASC");
+        $aHandlers = $oDb->getAll("SELECT `id`, `class`, `file`, `service_call` FROM `sys_alerts_handlers` ORDER BY `id` ASC");
         foreach ($aHandlers as $aHandler)
-            $aResult['handlers'][$aHandler['id']] = array('class' => $aHandler['class'], 'file' => $aHandler['file'], 'eval' => $aHandler['eval']);
+            $aResult['handlers'][$aHandler['id']] = array('class' => $aHandler['class'], 'file' => $aHandler['file'], 'service_call' => $aHandler['service_call']);
 
         $oCache = $oDb->getDbCacheObject();
         $oCache->setData ($oDb->genDbCacheKey('sys_alerts'), $aResult);

+ 1 - 1
inc/classes/BxDolCron.php

@@ -29,7 +29,7 @@ defined('BX_DOL') or die('hack attempt');
  *
  *  class - class name which will run
  *  file - path to class file
- *  eval - source code which will run
+ *  service_call - serialized service call which will be run
  *
  * The time numbers can be given as a comma separated list of simple numbers,
  * ranges("2-5" is the same as "2,3,4,5"). A single "*" can be used in a field to indicate all

+ 2 - 2
inc/classes/BxDolImageTranscoder.php

@@ -178,7 +178,7 @@ class BxDolImageTranscoder extends BxDol implements iBxDolFactoryObject
     /**
      * Called automatically, upon local(transcoded) file deletetion.
      */
-    static public function onAlertResponseFileDeleteLocal ($sObject, $oAlert) {
+    static public function onAlertResponseFileDeleteLocal ($oAlert, $sObject) {
         $oTranscoder = BxDolImageTranscoder::getObjectInstance($sObject);
         if (!$oTranscoder)
             return;
@@ -192,7 +192,7 @@ class BxDolImageTranscoder extends BxDol implements iBxDolFactoryObject
     /**
      * Called automatically, upon original file deletetion.
      */
-    static public function onAlertResponseFileDeleteOrig ($sObject, $oAlert) {
+    static public function onAlertResponseFileDeleteOrig ($oAlert, $sObject) {
         $oTranscoder = BxDolImageTranscoder::getObjectInstance($sObject);
         if (!$oTranscoder)
             return;

+ 10 - 5
inc/classes/BxDolImageTranscoderQuery.php

@@ -73,12 +73,12 @@ class BxDolImageTranscoderQuery extends BxDolDb {
 
     public function registerHandlers () {
 
-        if (!$this->registerHandler ('getAlertHandlerNameLocal', 'onAlertResponseFileDeleteLocal', $this->_aObject['object'], $this->_aObject['storage_object']))
+        if (!$this->registerHandler ('getAlertHandlerNameLocal', 'alert_response_file_delete_local', $this->_aObject['object'], $this->_aObject['storage_object']))
             return false;
 
         // add handler for original storage engine
         if ('Storage' == $this->_aObject['source_type']) // if original storage is "Storage", not "Folder"
-            if (!$this->registerHandler ('getAlertHandlerNameOrig', 'onAlertResponseFileDeleteOrig', $this->_aObject['object'], $this->_aObject['source_params']['object']))
+            if (!$this->registerHandler ('getAlertHandlerNameOrig', 'alert_response_file_delete_orig', $this->_aObject['object'], $this->_aObject['source_params']['object']))
                 return false;
 
         return true;
@@ -97,15 +97,20 @@ class BxDolImageTranscoderQuery extends BxDolDb {
         return true;
     }    
 
-    protected function registerHandler ($sHandlerNameFunc, $sEvalFunc, $sObject, $sUnit) {
+    protected function registerHandler ($sHandlerNameFunc, $sServiceFunc, $sObject, $sUnit) {
 
         $sHandlerName = $this->$sHandlerNameFunc ();
         $iHandlerId = $this->getAlertHandlerId ($sHandlerName);
         if ($iHandlerId) // if handler already exists, do nothing
             return true;
 
-        $sEval = 'bx_import("BxDolImageTranscoder"); BxDolImageTranscoder::' . $sEvalFunc . '("' . $sObject . '", $this);';
-        $sQuery = $this->prepare("INSERT INTO `sys_alerts_handlers` SET `name` = ?, `eval` = ?", $sHandlerName, $sEval);
+        $sServiceCall = serialize(array(
+        	'module' => 'system',
+        	'method' => $sServiceFunc,
+        	'params' => array($sObject),
+        	'class' => 'TemplImageServices'
+        ));
+        $sQuery = $this->prepare("INSERT INTO `sys_alerts_handlers` SET `name` = ?, `service_call` = ?", $sHandlerName, $sServiceCall);
         if (!$this->query($sQuery))
             return false;
         $iHandlerId = $this->lastId();

+ 22 - 25
install/sql/system.sql

@@ -7,7 +7,7 @@ SET @sSysVersion = '8.0.0';
 -- --------------------------------------------------------
 
 SET NAMES 'utf8';
-DROP TABLE IF EXISTS `sys_keys`, `sys_objects_editor`, `sys_objects_captcha`, `sys_objects_social_sharing`, `sys_objects_cmts`, `sys_cmts_images`, `sys_cmts_images_preview`, `sys_cmts_images2entries`, `sys_email_templates`, `sys_options`, sys_options_types, `sys_options_categories`, `sys_localization_categories`, `sys_localization_keys`, `sys_localization_languages`, `sys_localization_strings`, `sys_acl_actions`, `sys_acl_actions_track`, `sys_acl_matrix`, `sys_acl_levels`, `sys_sessions`, `sys_acl_levels_members`, `sys_objects_search`, `sys_stat_site`, `sys_alerts`, `sys_alerts_handlers`, `sys_injections`, `sys_injections_admin`, `sys_modules`, `sys_modules_file_tracks`, `sys_permalinks`, `sys_objects_privacy`, `sys_privacy_defaults`, `sys_privacy_groups`, `sys_objects_auths`, `sys_objects_vote`, `sys_objects_view`, `sys_cron_jobs`, `sys_objects_storage`, `sys_objects_uploader`, `sys_storage_user_quotas`, `sys_storage_tokens`, `sys_storage_ghosts`, `sys_storage_deletions`, `sys_storage_mime_types`, `sys_objects_transcoder_images`, `sys_transcoder_images_files`, `sys_transcoder_images_filters`, `sys_accounts`, `sys_profiles`, `sys_objects_form`, `sys_form_displays`, `sys_form_inputs`, `sys_form_display_inputs`, `sys_form_pre_lists`, `sys_form_pre_values`, `sys_menu_templates`, `sys_objects_menu`, `sys_menu_sets`, `sys_menu_items`, `sys_objects_grid`, `sys_grid_fields`, `sys_grid_actions`, `sys_objects_connection`, `sys_profiles_conn_subscriptions`, `sys_profiles_conn_friends`, `sys_objects_page`, `sys_pages_layouts`, `sys_pages_design_boxes`, `sys_pages_blocks`, `sys_images`, `sys_std_pages`, `sys_std_widgets`, `sys_std_pages_widgets`;
+DROP TABLE IF EXISTS `sys_keys`, `sys_objects_editor`, `sys_objects_captcha`, `sys_objects_social_sharing`, `sys_objects_cmts`, `sys_cmts_images`, `sys_cmts_images_preview`, `sys_cmts_images2entries`, `sys_email_templates`, `sys_options`, sys_options_types, `sys_options_categories`, `sys_localization_categories`, `sys_localization_keys`, `sys_localization_languages`, `sys_localization_strings`, `sys_acl_actions`, `sys_acl_actions_track`, `sys_acl_matrix`, `sys_acl_levels`, `sys_sessions`, `sys_acl_levels_members`, `sys_objects_search`, `sys_stat_site`, `sys_alerts`, `sys_alerts_handlers`, `sys_injections`, `sys_injections_admin`, `sys_modules`, `sys_modules_file_tracks`, `sys_permalinks`, `sys_objects_privacy`, `sys_privacy_defaults`, `sys_privacy_groups`, `sys_objects_auths`, `sys_objects_vote`, `sys_objects_view`, `sys_cron_jobs`, `sys_objects_storage`, `sys_objects_uploader`, `sys_storage_user_quotas`, `sys_storage_tokens`, `sys_storage_ghosts`, `sys_storage_mime_types`, `sys_objects_transcoder_images`, `sys_transcoder_images_files`, `sys_transcoder_images_filters`, `sys_accounts`, `sys_profiles`, `sys_objects_form`, `sys_form_displays`, `sys_form_inputs`, `sys_form_display_inputs`, `sys_form_pre_lists`, `sys_form_pre_values`, `sys_menu_templates`, `sys_objects_menu`, `sys_menu_sets`, `sys_menu_items`, `sys_objects_grid`, `sys_grid_fields`, `sys_grid_actions`, `sys_objects_connection`, `sys_profiles_conn_subscriptions`, `sys_profiles_conn_friends`, `sys_objects_page`, `sys_pages_layouts`, `sys_pages_design_boxes`, `sys_pages_blocks`, `sys_images`, `sys_std_pages`, `sys_std_widgets`, `sys_std_pages_widgets`;
 ALTER DATABASE DEFAULT CHARACTER SET 'utf8' COLLATE 'utf8_unicode_ci';
 
 
@@ -150,8 +150,7 @@ INSERT INTO `sys_email_templates` (`Module`, `NameSystem`, `Name`, `Subject`, `B
 ('system', '_sys_et_txt_name_system_password_reset', 't_PasswordReset', '_sys_et_txt_subject_password_reset', '_sys_et_txt_body_password_reset'),
 ('system', '_sys_et_txt_name_system_mem_expiration', 't_MemExpiration', '_sys_et_txt_subject_mem_expiration', '_sys_et_txt_body_mem_expiration'),
 ('system', '_sys_et_txt_name_system_mem_changed', 't_MemChanged', '_sys_et_txt_subject_mem_changed', '_sys_et_txt_body_mem_changed'),
-('system', '_sys_et_txt_name_system_comment_replied', 't_CommentReplied', '_sys_et_txt_subject_comment_replied', '_sys_et_txt_body_comment_replied'),
-('system', '_sys_et_txt_name_system_delayed_module_uninstall', 't_DelayedModuleUninstall', '_sys_et_txt_subject_delayed_module_uninstall', '_sys_et_txt_body_delayed_module_uninstall');
+('system', '_sys_et_txt_name_system_comment_replied', 't_CommentReplied', '_sys_et_txt_subject_comment_replied', '_sys_et_txt_body_comment_replied');
 
 -- --------------------------------------------------------
 
@@ -166,7 +165,8 @@ CREATE TABLE `sys_options` (
   `value` mediumtext NOT NULL,
   `type` enum('digit','text','checkbox','select','combobox','file','list') NOT NULL default 'digit',
   `extra` text NOT NULL default '',
-  `check` text NOT NULL,
+  `check` varchar(32) NOT NULL,
+  `check_params` text NOT NULL,
   `check_error` varchar(255) NOT NULL default '',
   `order` int(11) default '0',
   PRIMARY KEY (`id`),
@@ -246,7 +246,7 @@ INSERT INTO `sys_options_categories`(`type_id`, `name`, `caption`, `hidden`, `or
 SET @iCategoryId = LAST_INSERT_ID();
 
 INSERT INTO `sys_options`(`category_id`, `name`, `caption`, `value`, `type`, `extra`, `check`, `check_error`, `order`) VALUES
-(@iCategoryId, 'lang_default', '_adm_stg_cpt_option_lang_default', '', 'select', 'PHP:bx_import(''BxDolLanguages''); $aValues = BxDolLanguages::getInstance()->getLanguages(false, true); $aResult = array(); foreach($aValues as $sKey => $sValue) $aResult[] = array(\'key\' => $sKey, \'value\' => $sValue); return $aResult;', '', '', 1),
+(@iCategoryId, 'lang_default', '_adm_stg_cpt_option_lang_default', '', 'select', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:13:"get_languages";s:6:"params";a:2:{i:0;b:0;i:1;b:1;}s:5:"class";s:22:"TemplLanguagesServices";}', '', '', 1),
 
 (@iCategoryId, 'sys_format_date', '_adm_stg_cpt_option_sys_format_date', 'D MMM YYYY', 'digit', '', '', '', 3),
 (@iCategoryId, 'sys_format_time', '_adm_stg_cpt_option_sys_format_time', 'HH:mm', 'digit', '', '', '', 4),
@@ -261,7 +261,7 @@ INSERT INTO `sys_options_categories`(`type_id`, `name`, `caption`, `hidden`, `or
 SET @iCategoryId = LAST_INSERT_ID();
 
 INSERT INTO `sys_options`(`category_id`, `name`, `caption`, `value`, `type`, `extra`, `check`, `check_error`, `order`) VALUES
-(@iCategoryId, 'template', '_adm_stg_cpt_option_template', '', 'select', 'PHP:$aValues = get_templates_array(); $aResult = array(); foreach($aValues as $sKey => $sValue) $aResult[] = array(\'key\' => $sKey, \'value\' => $sValue); return $aResult;', 'bx_import(\'BxDolModuleQuery\'); return (strlen($arg0) > 0 && BxDolModuleQuery::getInstance()->isEnabled($arg0)) ? true : false;', 'Template cannot be empty and must have a valid name.', 1),
+(@iCategoryId, 'template', '_adm_stg_cpt_option_template', '', 'select', 'a:3:{s:6:"module";s:6:"system";s:6:"method";s:13:"get_templates";s:5:"class";s:21:"TemplTemplateServices";}', 'Template', '_adm_stg_err_option_template', 1),
 (@iCategoryId, 'enable_template', '_adm_stg_cpt_option_enable_template', 'on', 'checkbox', '', '', '', 2),
 
 (@iCategoryId, 'sys_template_page_width_min', '_adm_stg_cpt_option_sys_template_page_width_min', '774', 'digit', '', '', '', 3),
@@ -310,8 +310,8 @@ INSERT INTO `sys_options`(`category_id`, `name`, `caption`, `value`, `type`, `ex
 (@iCategoryId, 'sys_oauth_secret', '_adm_stg_cpt_option_sys_oauth_secret', '', 'digit', '', '', '', 5),
 (@iCategoryId, 'boonexAffID', '_adm_stg_cpt_option_boonex_aff_id', '', 'digit', '', '', '', 6),
 
-(@iCategoryId, 'currency_code', '_adm_stg_cpt_option_currency_code', 'USD', 'select', 'USD,EURO', 'return strlen($arg0) > 0;', 'Cannot be empty.', 7),
-(@iCategoryId, 'currency_sign', '_adm_stg_cpt_option_currency_sign', '$', 'digit', '', 'return strlen($arg0) > 0;', 'Cannot be empty.', 8),
+(@iCategoryId, 'currency_code', '_adm_stg_cpt_option_currency_code', 'USD', 'select', 'USD,EURO', 'Avail', '_adm_stg_err_option_currency_code', 7),
+(@iCategoryId, 'currency_sign', '_adm_stg_cpt_option_currency_sign', '$', 'digit', '', 'Avail', '_adm_stg_err_option_currency_sign', 8),
 
 (@iCategoryId, 'enable_gd', '_adm_stg_cpt_option_enable_gd', 'on', 'checkbox', '', '', '', 9),
 (@iCategoryId, 'useLikeOperator', '_adm_stg_cpt_option_use_like_operator', 'on', 'checkbox', '', '', '', 10);
@@ -728,7 +728,6 @@ CREATE TABLE `sys_modules` (
   `dependencies` varchar(255) NOT NULL default '',
   `date` int(11) unsigned NOT NULL default '0',
   `enabled` tinyint(1) NOT NULL default '0',
-  `pending_uninstall` tinyint(4) NOT NULL,
   PRIMARY KEY  (`id`),
   UNIQUE KEY `name` (`name`),
   UNIQUE KEY `path` (`path`),
@@ -882,7 +881,7 @@ CREATE TABLE `sys_alerts_handlers` (
   `name` varchar(128) NOT NULL default '',
   `class` varchar(128) NOT NULL default '',
   `file` varchar(255) NOT NULL default '',
-  `eval` text NOT NULL default '', 
+  `service_call` text NOT NULL default '', 
   PRIMARY KEY  (`id`),
   UNIQUE KEY `name` (`name`)
 ) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
@@ -963,20 +962,28 @@ INSERT INTO `sys_privacy_groups`(`id`, `title`, `check`, `active`, `visible`) VA
 
 -- --------------------------------------------------------
 
+
+--
+-- Table structure for table `sys_cron_jobs`
+--
+
 CREATE TABLE `sys_cron_jobs` (
   `id` int(11) unsigned NOT NULL auto_increment,
   `name` varchar(128) NOT NULL default '',
   `time` varchar(128) NOT NULL default '*',
   `class` varchar(128) NOT NULL default '',
   `file` varchar(255) NOT NULL default '',
-  `eval` text NOT NULL default '', 
+  `service_call` text NOT NULL default '', 
   PRIMARY KEY  (`id`)
 ) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
 
-INSERT INTO `sys_cron_jobs` (`name`, `time`, `class`, `file`, `eval`) VALUES
+--
+-- Dumping data for table `sys_cron_jobs`
+--
+
+INSERT INTO `sys_cron_jobs` (`name`, `time`, `class`, `file`, `service_call`) VALUES
 ('cmd', '0 0 * * *', 'BxDolCronCmd', 'inc/classes/BxDolCronCmd.php', ''),
-('notifies', '*/10 * * * *', 'BxDolCronNotifies', 'inc/classes/BxDolCronNotifies.php', ''),
-('sys_storage', '* * * * *', 'BxDolCronStorage', 'inc/classes/BxDolCronStorage.php', '');
+('notifies', '*/10 * * * *', 'BxDolCronNotifies', 'inc/classes/BxDolCronNotifies.php', '');
 
 -- --------------------------------------------------------
 
@@ -1035,20 +1042,10 @@ CREATE TABLE IF NOT EXISTS `sys_storage_ghosts` (
   KEY `profile_object_content` (`profile_id`,`object`,`content_id`)
 ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
 
-CREATE TABLE IF NOT EXISTS `sys_storage_deletions` (
-  `id` int(11) NOT NULL AUTO_INCREMENT,
-  `object` varchar(64) NOT NULL,
-  `file_id` int(11) NOT NULL,
-  `requested` int(10) unsigned NOT NULL,
-  PRIMARY KEY (`id`),
-  UNIQUE KEY `object_file_id` (`object`,`file_id`),
-  KEY `requested` (`requested`)
-) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
-
 CREATE TABLE IF NOT EXISTS `sys_storage_mime_types` (
   `ext` varchar(32) NOT NULL,
   `mime_type` varchar(128) NOT NULL,
-  `icon` varchar(255) NOT NULL,
+  `icon` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
   PRIMARY KEY (`ext`)
 ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
 

+ 2 - 2
modules/boonex/antispam/install/sql/enable.sql

@@ -184,7 +184,7 @@ INSERT INTO `sys_form_display_inputs`(`display_name`, `input_name`, `visible_for
 
 -- alerts
 
-INSERT INTO `sys_alerts_handlers` (`name`, `class`, `file`, `eval`) VALUES 
+INSERT INTO `sys_alerts_handlers` (`name`, `class`, `file`, `service_call`) VALUES 
 ('bx_antispam', 'BxAntispamAlertsResponse', 'modules/boonex/antispam/classes/BxAntispamAlertsResponse.php', '');
 SET @iHandler := LAST_INSERT_ID();
 
@@ -200,6 +200,6 @@ INSERT INTO `sys_email_templates` (`Module`, `NameSystem`, `Name`, `Subject`, `B
 
 -- cron
 
-INSERT INTO `sys_cron_jobs` (`name`, `time`, `class`, `file`, `eval`) VALUES
+INSERT INTO `sys_cron_jobs` (`name`, `time`, `class`, `file`, `service_call`) VALUES
 ('bx_antispam_pruning', '0 0 * * *', 'BxAntispamCronPruning', 'modules/boonex/antispam/classes/BxAntispamCronPruning.php', '');
 

+ 1 - 1
modules/boonex/convos/install/sql/enable.sql

@@ -177,7 +177,7 @@ INSERT INTO `sys_objects_view` (`name`, `table_track`, `period`, `is_on`, `trigg
 
 -- ALERTS
 
-INSERT INTO `sys_alerts_handlers` (`name`, `class`, `file`, `eval`) VALUES 
+INSERT INTO `sys_alerts_handlers` (`name`, `class`, `file`, `service_call`) VALUES 
 ('bx_convos', 'BxCnvAlertsResponse', 'modules/boonex/convos/classes/BxCnvAlertsResponse.php', '');
 SET @iHandler := LAST_INSERT_ID();
 

+ 10 - 0
modules/boonex/developer/classes/BxDevFunctions.php

@@ -33,6 +33,16 @@ class BxDevFunctions {
         $aInputs['object']['type'] = 'select';
         $aInputs['object']['values'] = array_merge(array('' => _t('_bx_dev_frm_txt_select_object')), $aInputs['object']['values']);
         $aInputs['object']['value'] = $aParams['object'];
+
+        $sTrlTypePostfix = '_translatable';
+        $sTrlCheckFuncPostfix = 'Translatable';
+        foreach($aInputs as $sName => $aInput)
+        	if(isset($aInput['type']) && stripos($aInput['type'], $sTrlTypePostfix) !== false) {
+        		$aInputs[$sName]['type'] = str_ireplace($sTrlTypePostfix, '', $aInput['type']);
+
+        		if(isset($aInput['checker']['func']) && stripos($aInput['checker']['func'], $sTrlCheckFuncPostfix) !== false)
+        			$aInputs[$sName]['checker']['func'] = str_ireplace($sTrlCheckFuncPostfix, '', $aInput['checker']['func']);
+        	}
     }
 
     public static function serializeString($sValue) {

+ 4 - 0
modules/boonex/english/data/langs/system.xml

@@ -1090,7 +1090,9 @@
 	<string name="_adm_stg_cpt_category_templates"><![CDATA[Templates]]></string>
 	<string name="_adm_stg_cpt_option_boonex_aff_id"><![CDATA[My BoonEx Affiliate ID]]></string>
 	<string name="_adm_stg_cpt_option_currency_code"><![CDATA[Currency code (for checkout system)]]></string>
+	<string name="_adm_stg_err_option_currency_code"><![CDATA[Cannot be empty.]]></string>
 	<string name="_adm_stg_cpt_option_currency_sign"><![CDATA[Currency sign (for display purposes only)]]></string>
+	<string name="_adm_stg_err_option_currency_sign"><![CDATA[Cannot be empty.]]></string>
 	<string name="_adm_stg_cpt_option_enable_gd"><![CDATA[Use GD library for image processing]]></string>
 	<string name="_adm_stg_cpt_option_enable_template"><![CDATA[Show Template Switcher]]></string>
 	<string name="_adm_stg_cpt_option_expire_notification_days"><![CDATA[Number of days before membership expiration to notify members ( -1 = after expiration )]]></string>
@@ -1140,9 +1142,11 @@
 	<string name="_adm_stg_cpt_option_sys_template_page_width_max"><![CDATA[Max page width(in pixels)]]></string>
 	<string name="_adm_stg_cpt_option_sys_template_page_width_min"><![CDATA[Min page width(in pixels)]]></string>
 	<string name="_adm_stg_cpt_option_template"><![CDATA[Default Template]]></string>
+	<string name="_adm_stg_err_option_template"><![CDATA[Template cannot be empty and must have a valid name.]]></string>
 	<string name="_adm_stg_cpt_option_use_like_operator"><![CDATA[Use operator LIKE for search (recommended for small content)]]></string>
 	<string name="_adm_stg_cpt_type_system"><![CDATA[System]]></string>
 	<string name="_adm_stg_scs_save"><![CDATA[Settings were successfully saved]]></string>
+	<string name="_adm_stg_err_save_error_message"><![CDATA[Error in '{0}': {1}]]></string>
 	<string name="_adm_str_cpt_files_file"><![CDATA[File]]></string>
 	<string name="_adm_str_cpt_files_version"><![CDATA[Version]]></string>
 	<string name="_adm_str_err_cannot_connect_to_ftp"><![CDATA[Cannot connect to FTP server. Please check FTP access details in Settings -> Other.]]></string>

+ 1 - 1
modules/boonex/organizations/install/sql/enable.sql

@@ -12,7 +12,7 @@ SET @iCategId = LAST_INSERT_ID();
 
 INSERT INTO `sys_options` (`name`, `value`, `category_id`, `caption`, `type`, `extra`, `check`, `check_error`, `order`) VALUES
 ('bx_organizations_autoapproval', 'on', @iCategId, '_bx_orgs_option_autoapproval', 'checkbox', '', '', '', 1),
-('bx_organizations_default_acl_level', '2', @iCategId, '_bx_orgs_option_default_acl_level', 'select', 'PHP:bx_import(''BxDolAcl''); return BxDolAcl::getInstance()->getMemberships(false, true);', '', '', 2),
+('bx_organizations_default_acl_level', '2', @iCategId, '_bx_orgs_option_default_acl_level', 'select', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:15:"get_memberships";s:6:"params";a:2:{i:0;b:0;i:1;b:1;}s:5:"class";s:16:"TemplAclServices";}', '', '', 2),
 ('bx_organizations_num_connections_quick', '4', @iCategId, '_bx_orgs_option_num_connections_quick', 'digit', '', '', '', 10),
 ('bx_organizations_num_rss', '10', @iCategId, '_bx_orgs_option_num_rss', 'digit', '', '', '', 12);
 

+ 1 - 1
modules/boonex/persons/install/sql/enable.sql

@@ -12,7 +12,7 @@ SET @iCategId = LAST_INSERT_ID();
 
 INSERT INTO `sys_options` (`name`, `value`, `category_id`, `caption`, `type`, `extra`, `check`, `check_error`, `order`) VALUES
 ('bx_persons_autoapproval', 'on', @iCategId, '_bx_persons_option_autoapproval', 'checkbox', '', '', '', 1),
-('bx_persons_default_acl_level', '2', @iCategId, '_bx_persons_option_default_acl_level', 'select', 'PHP:bx_import(''BxDolAcl''); return BxDolAcl::getInstance()->getMemberships(false, true);', '', '', 2),
+('bx_persons_default_acl_level', '2', @iCategId, '_bx_persons_option_default_acl_level', 'select', 'a:4:{s:6:"module";s:6:"system";s:6:"method";s:15:"get_memberships";s:6:"params";a:2:{i:0;b:0;i:1;b:1;}s:5:"class";s:16:"TemplAclServices";}', '', '', 2),
 ('bx_persons_num_connections_quick', '4', @iCategId, '_bx_persons_option_num_connections_quick', 'digit', '', '', '', 10),
 ('bx_persons_num_rss', '10', @iCategId, '_bx_persons_option_num_rss', 'digit', '', '', '', 12);
 

+ 1 - 1
modules/boonex/profiler/install/sql/enable.sql

@@ -40,7 +40,7 @@ INSERT INTO `sys_options` (`category_id`, `name`, `value`, `caption`, `type`, `e
 
 -- ALERTS
 
-INSERT INTO `sys_alerts_handlers` (`name`, `class`, `file`, `eval`) VALUES 
+INSERT INTO `sys_alerts_handlers` (`name`, `class`, `file`, `service_call`) VALUES 
 ('bx_profiler', 'BxProfilerAlertsResponse', 'modules/boonex/profiler/classes/BxProfilerAlertsResponse.php', '');
 SET @iHandler := LAST_INSERT_ID();
 

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

@@ -1526,6 +1526,7 @@ Please click "Continue" below to navigate to the home page of the site.]]></stri
 	<!-- Settings: Templates -->
 	<string name="_adm_stg_cpt_category_templates"><![CDATA[Templates]]></string>
 	<string name="_adm_stg_cpt_option_template"><![CDATA[Default Template]]></string>
+	<string name="_adm_stg_err_option_template"><![CDATA[Template cannot be empty and must have a valid name.]]></string>
 	<string name="_adm_stg_cpt_option_enable_template"><![CDATA[Show Template Switcher]]></string>
 	<string name="_adm_stg_cpt_option_sys_template_page_width_min"><![CDATA[Min page width(in pixels)]]></string>
 	<string name="_adm_stg_cpt_option_sys_template_page_width_max"><![CDATA[Max page width(in pixels)]]></string>
@@ -1556,7 +1557,9 @@ Please click "Continue" below to navigate to the home page of the site.]]></stri
 	<string name="_adm_stg_cpt_option_sys_oauth_secret"><![CDATA[BoonEx account secret]]></string>
 	<string name="_adm_stg_cpt_option_boonex_aff_id"><![CDATA[My BoonEx Affiliate ID]]></string>
 	<string name="_adm_stg_cpt_option_currency_code"><![CDATA[Currency code (for checkout system)]]></string>
+	<string name="_adm_stg_err_option_currency_code"><![CDATA[Cannot be empty.]]></string>
 	<string name="_adm_stg_cpt_option_currency_sign"><![CDATA[Currency sign (for display purposes only)]]></string>
+	<string name="_adm_stg_err_option_currency_sign"><![CDATA[Cannot be empty.]]></string>
 	<string name="_adm_stg_cpt_option_enable_gd"><![CDATA[Use GD library for image processing]]></string>
 	<string name="_adm_stg_cpt_option_use_like_operator"><![CDATA[Use operator LIKE for search (recommended for small content)]]></string>
 	<string name="_adm_stg_cpt_option_"><![CDATA[]]></string>
@@ -1613,6 +1616,7 @@ Please click "Continue" below to navigate to the home page of the site.]]></stri
 
 	<string name="_adm_stg_err_save"><![CDATA[Cannot save settings]]></string>
 	<string name="_adm_stg_scs_save"><![CDATA[Settings were successfully saved]]></string>
+	<string name="_adm_stg_err_save_error_message"><![CDATA[Error in '{0}': {1}]]></string>
 
 	<!-- Store -->
 	<string name="_adm_page_cpt_store"><![CDATA[Store]]></string>

+ 0 - 28
modules/boonex/sites/classes/BxSitesModule.php

@@ -159,34 +159,6 @@ class BxSitesModule extends BxDolModule
         );
     }
 
-    public function serviceResponse($oAlert)
-    {
-    	if($oAlert->sUnit != 'account' || !in_array($oAlert->sAction, array('login')))
-    		return;
-
-		bx_import('BxDolSession');
-		$sDomain = BxDolSession::getInstance()->getUnsetValue('bx_sites_domain');
-		if($sDomain === false)
-			return;
-
-		$iAccountId = $this->_oDb->insertAccount(array(
-			'owner_id' => $oAlert->iObject,
-			'domain' => $sDomain,
-			'created' => time(),
-			'status' => BX_SITES_ACCOUNT_STATUS_UNCONFIRMED
-		));
-
-		if(!$iAccountId)
-			return;
-
-		$oAccount = $this->getObject('Account');
-		$oAccount->onAccountCreated($iAccountId);
-
-		$sUrl = $this->startSubscription($iAccountId);
-		header('Location: ' . $sUrl);
-		exit;
-    }
-
     // ====== ACTION METHODS
 	public function actionIpn()
 	{

+ 64 - 0
modules/boonex/sites/classes/BxSitesResponse.php

@@ -0,0 +1,64 @@
+<?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    Timeline Timeline
+ * @ingroup     DolphinModules
+ *
+ * @{
+ */
+
+bx_import('BxDolAlerts');
+
+class BxSitesResponse extends BxDolAlertsResponse
+{
+    protected $_oModule;
+
+    /**
+     * Constructor
+     * @param BxTimelineModule $oModule - an instance of current module
+     */
+    public function __construct()
+    {
+        parent::__construct();
+
+        bx_import('BxDolModule');
+        $this->_oModule = BxDolModule::getInstance('bx_sites');
+    }
+
+    /**
+     * Overwtire the method of parent class.
+     *
+     * @param BxDolAlerts $oAlert an instance of alert.
+     */
+    public function response($oAlert)
+    {
+        if($oAlert->sUnit != 'account' || !in_array($oAlert->sAction, array('login')))
+    		return;
+
+		bx_import('BxDolSession');
+		$sDomain = BxDolSession::getInstance()->getUnsetValue('bx_sites_domain');
+		if($sDomain === false)
+			return;
+
+		$iAccountId = $this->_oModule->_oDb->insertAccount(array(
+			'owner_id' => $oAlert->iObject,
+			'domain' => $sDomain,
+			'created' => time(),
+			'status' => BX_SITES_ACCOUNT_STATUS_UNCONFIRMED
+		));
+
+		if(!$iAccountId)
+			return;
+
+		$oAccount = $this->_oModule->getObject('Account');
+		$oAccount->onAccountCreated($iAccountId);
+
+		$sUrl = $this->_oModule->startSubscription($iAccountId);
+		header('Location: ' . $sUrl);
+		exit;
+    }
+}
+
+/** @} */ 

+ 2 - 2
modules/boonex/sites/install/sql/enable.sql

@@ -132,8 +132,8 @@ INSERT INTO `sys_grid_actions` (`object`, `type`, `name`, `title`, `icon`, `conf
 ('bx_sites_overview', 'independent', 'suspended', '_bx_sites_grid_overview_btn_suspended', '', 0, 5);
 
 -- ALERTS
-INSERT INTO `sys_alerts_handlers` (`name`, `class`, `file`, `eval`) VALUES 
-('bx_sites', '', '', 'BxDolService::call(''bx_sites'', ''response'', array($this));');
+INSERT INTO `sys_alerts_handlers` (`name`, `class`, `file`, `service_call`) VALUES 
+('bx_sites', 'BxSitesResponse', 'modules/boonex/sites/classes/BxSitesResponse.php', '');
 SET @iHandler := LAST_INSERT_ID();
 
 INSERT INTO `sys_alerts` (`unit`, `action`, `handler_id`) VALUES

+ 22 - 0
modules/boonex/timeline/classes/BxTimelineFormCheckerHelper.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    Timeline Timeline
+ * @ingroup     DolphinModules
+ *
+ * @{
+ */
+
+bx_import('BxDolStudioForm');
+
+class BxTimelineFormCheckerHelper extends BxDolStudioFormCheckerHelper
+{
+	function checkGreaterThen($sVal, $iLimit)
+    {
+    	return (int)$sVal > (int)$iLimit;
+    }
+}
+
+/** @} */ 

+ 6 - 7
modules/boonex/timeline/classes/BxTimelineModule.php

@@ -314,13 +314,6 @@ class BxTimelineModule extends BxDolModule
         return $aResults;
     }
 
-	public function serviceResponse($oAlert)
-    {
-    	bx_import('Response', $this->_aModule);
-        $oResponse = new BxTimelineResponse($this);
-        $oResponse->response($oAlert);
-    }
-
     /*
 	 * Get Post block for a separate page. 
 	 */
@@ -476,6 +469,12 @@ class BxTimelineModule extends BxDolModule
 		return $this->serviceGetShareCounter($sType, $sAction, $iObjectId);
     }
 
+    public function serviceGetSettingsCheckerHelper()
+    {
+    	bx_import('FormCheckerHelper', $this->_aModule);
+    	return 'BxTimelineFormCheckerHelper';
+    }
+
     /*
      * COMMON METHODS 
      */

+ 3 - 2
modules/boonex/timeline/classes/BxTimelineResponse.php

@@ -19,11 +19,12 @@ class BxTimelineResponse extends BxDolAlertsResponse
      * Constructor
      * @param BxTimelineModule $oModule - an instance of current module
      */
-    public function __construct($oModule)
+    public function __construct()
     {
         parent::__construct();
 
-        $this->_oModule = $oModule;
+        bx_import('BxDolModule');
+        $this->_oModule = BxDolModule::getInstance('bx_timeline');
     }
 
     /**

+ 1 - 0
modules/boonex/timeline/install/langs/en.xml

@@ -9,6 +9,7 @@
 	<string name="_bx_timeline_option_rss_length"><![CDATA[The length of RSS feed]]></string>
 	<string name="_bx_timeline_option_events_hide"><![CDATA[Hide events from Timeline]]></string>
 	<string name="_bx_timeline_option_chars_display_max"><![CDATA[Max number of displayed character in text post]]></string>
+	<string name="_bx_timeline_option_err_chars_display_max"><![CDATA[Enter the number which should be greater then 150.]]></string>
 
 	<string name="_bx_timeline_form_post"><![CDATA[Post]]></string>
 	<string name="_bx_timeline_form_post_display_add"><![CDATA[Write Post]]></string>

+ 9 - 9
modules/boonex/timeline/install/sql/enable.sql

@@ -56,13 +56,13 @@ INSERT INTO `sys_options_categories` (`type_id`, `name`, `caption`, `order`)
 VALUES (@iTypeId, 'bx_timeline', '_bx_timeline', 1);
 SET @iCategId = LAST_INSERT_ID();
 
-INSERT INTO `sys_options` (`name`, `value`, `category_id`, `caption`, `type`, `check`, `check_error`, `extra`, `order`) VALUES
-('bx_timeline_enable_delete', 'on', @iCategId, '_bx_timeline_option_enable_delete', 'checkbox', '', '', '', 1),
-('bx_timeline_events_per_page_profile', '10', @iCategId, '_bx_timeline_option_events_per_page_profile', 'digit', '', '', '', 2),
-('bx_timeline_events_per_page_account', '20', @iCategId, '_bx_timeline_option_events_per_page_account', 'digit', '', '', '', 3),
-('bx_timeline_rss_length', '5', @iCategId, '_bx_timeline_option_rss_length', 'digit', '', '', '', 4),
-('bx_timeline_events_hide', '', @iCategId, '_bx_timeline_option_events_hide', 'list', '', '', 'PHP:return BxDolService::call(\'bx_timeline\', \'get_actions_checklist\');', 5),
-('bx_timeline_chars_display_max', '300', @iCategId, '_bx_timeline_option_chars_display_max', 'digit', '', '', '', 6);
+INSERT INTO `sys_options` (`name`, `value`, `category_id`, `caption`, `type`, `check`, `check_params`, `check_error`, `extra`, `order`) VALUES
+('bx_timeline_enable_delete', 'on', @iCategId, '_bx_timeline_option_enable_delete', 'checkbox', '', '', '', '', 1),
+('bx_timeline_events_per_page_profile', '10', @iCategId, '_bx_timeline_option_events_per_page_profile', 'digit', '', '', '', '', 2),
+('bx_timeline_events_per_page_account', '20', @iCategId, '_bx_timeline_option_events_per_page_account', 'digit', '', '', '', '', 3),
+('bx_timeline_rss_length', '5', @iCategId, '_bx_timeline_option_rss_length', 'digit', '', '', '', '', 4),
+('bx_timeline_events_hide', '', @iCategId, '_bx_timeline_option_events_hide', 'list', '', '', '', 'a:2:{s:6:"module";s:11:"bx_timeline";s:6:"method";s:21:"get_actions_checklist";}', 5),
+('bx_timeline_chars_display_max', '300', @iCategId, '_bx_timeline_option_chars_display_max', 'digit', 'GreaterThen', 'a:1:{s:3:"min";i:150;}', '_bx_timeline_option_err_chars_display_max', '', 6);
 
 
 -- UPLOADERS
@@ -135,8 +135,8 @@ INSERT INTO `sys_acl_matrix` (`IDLevel`, `IDAction`) VALUES
 
 
 -- ALERTS
-INSERT INTO `sys_alerts_handlers`(`name`, `class`, `file`, `eval`) VALUES 
-('bx_timeline', '', '', 'BxDolService::call(\'bx_timeline\', \'response\', array($this));');
+INSERT INTO `sys_alerts_handlers`(`name`, `class`, `file`, `service_call`) VALUES 
+('bx_timeline', 'BxTimelineResponse', 'modules/boonex/timeline/classes/BxTimelineResponse.php', '');
 
 
 -- COMMENTS

+ 21 - 0
modules/boonex/uni/data/template/system/scripts/BxTemplAclServices.php

@@ -0,0 +1,21 @@
+<?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    DolphinCore Dolphin Core
+ * @{
+ */
+
+bx_import('BxBaseAclServices');
+
+/**
+ * @see BxBaseAclServices
+ */
+class BxTemplAclServices extends BxBaseAclServices {
+    public function __construct() {
+        parent::__construct();
+    }
+}
+
+/** @} */

+ 1 - 1
modules/boonex/uni/data/template/system/scripts/BxTemplCmtsServices.php

@@ -10,7 +10,7 @@
 bx_import('BxBaseCmtsServices');
 
 /**
- * @see BxBaseServices
+ * @see BxBaseCmtsServices
  */
 class BxTemplCmtsServices extends BxBaseCmtsServices {
     public function __construct() {

+ 21 - 0
modules/boonex/uni/data/template/system/scripts/BxTemplImageServices.php

@@ -0,0 +1,21 @@
+<?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    DolphinCore Dolphin Core
+ * @{
+ */
+
+bx_import('BxBaseImageServices');
+
+/**
+ * @see BxBaseImageServices
+ */
+class BxTemplImageServices extends BxBaseImageServices {
+    public function __construct() {
+        parent::__construct();
+    }
+}
+
+/** @} */

+ 21 - 0
modules/boonex/uni/data/template/system/scripts/BxTemplLanguagesServices.php

@@ -0,0 +1,21 @@
+<?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    DolphinCore Dolphin Core
+ * @{
+ */
+
+bx_import('BxBaseLanguagesServices');
+
+/**
+ * @see BxBaseLanguagesServices
+ */
+class BxTemplLanguagesServices extends BxBaseLanguagesServices {
+    public function __construct() {
+        parent::__construct();
+    }
+}
+
+/** @} */

+ 21 - 0
modules/boonex/uni/data/template/system/scripts/BxTemplTemplateServices.php

@@ -0,0 +1,21 @@
+<?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    DolphinCore Dolphin Core
+ * @{
+ */
+
+bx_import('BxBaseTemplateServices');
+
+/**
+ * @see BxBaseTemplateServices
+ */
+class BxTemplTemplateServices extends BxBaseTemplateServices {
+    public function __construct() {
+        parent::__construct();
+    }
+}
+
+/** @} */

+ 2 - 4
periodic/cron.php

@@ -129,10 +129,8 @@ function runJob($aJob)
         $oHandler = new $aJob['class']();
         $oHandler->processing();
     }
-    else if(!empty($aJob['eval'])) {
-        bx_import('BxDolService');
-        eval($aJob['eval']);
-    }
+    else if(!empty($aJob['service_call']) && BxDolService::isSerializedService($aJob['service_call']))
+		BxDolService::callSerialized($aJob['service_call']);
 }
 
 $oDb = BxDolDb::getInstance();

+ 8 - 2
studio/classes/BxDolStudioForm.php

@@ -17,7 +17,7 @@ class BxDolStudioForm extends BxBaseFormView {
     function BxDolStudioForm($aInfo, $oTemplate) {
         parent::BxBaseFormView($aInfo, $oTemplate !== false ? $oTemplate : BxDolStudioTemplate::getInstance());
 
-        $this->_sCheckerHelper = isset($this->aParams['checker_helper']) ? $this->aParams['checker_helper'] : 'BxDolStudioCheckerHelper';
+        $this->_sCheckerHelper = isset($this->aParams['checker_helper']) ? $this->aParams['checker_helper'] : 'BxDolStudioFormCheckerHelper';
     }
 
     function initChecker($aValues = array (), $aSpecificValues = array())  {
@@ -139,7 +139,7 @@ class BxDolStudioForm extends BxBaseFormView {
     }
 }
 
-class BxDolStudioCheckerHelper extends BxDolFormCheckerHelper {
+class BxDolStudioFormCheckerHelper extends BxDolFormCheckerHelper {
     function checkAvailTranslatable($sVal, $aName, $sMethod = BX_DOL_STUDIO_METHOD_DEFAULT, $bAll = true) {
         if(empty($sMethod) || empty($aName))
             return false;
@@ -179,5 +179,11 @@ class BxDolStudioCheckerHelper extends BxDolFormCheckerHelper {
 
         return $bAll ? true : false;
     }
+
+    function checkTemplate($sVal)
+    {
+    	bx_import('BxDolModuleQuery'); 
+    	return strlen($sVal) > 0 && BxDolModuleQuery::getInstance()->isEnabled($sVal);
+    }
 }
 /** @} */

+ 23 - 49
studio/classes/BxDolStudioInstaller.php

@@ -545,23 +545,30 @@ class BxDolStudioInstaller extends BxDolInstallerUtils {
         if(!isset($this->_aConfig[$sOperation . '_permissions']) || !is_array($this->_aConfig[$sOperation . '_permissions']))
             return BX_DOL_STUDIO_INSTALLER_FAILED;
 
+		$aChangeItems = array();
+		$aPermissions = $this->_aConfig[$sOperation . '_permissions'];
+		foreach($aPermissions as $sPermissions => $aFiles) {
+			$sCheckFunction = 'is' . ucfirst($sPermissions);
+			foreach($aFiles as $sFile) {
+				$sPath = bx_ltrim_str($this->_sModulePath . $sFile, BX_DIRECTORY_PATH_ROOT);
+				if(BxDolInstallerUtils::$sCheckFunction($sPath))
+					continue;
+
+				$aChangeItems[] = array('file' => $sFile, 'path' => $sPath, 'permissions' => $sPermissions);
+            }
+        }
+
+		if(empty($aChangeItems))
+			return BX_DOL_STUDIO_INSTALLER_SUCCESS;
+
         $oFile = $this->_getFileManager();
         if(empty($oFile))
         	return array('code' => BX_DOL_STUDIO_INSTALLER_FAILED);
 
-        $aResult = array();
-        $aPermissions = $this->_aConfig[$sOperation . '_permissions'];
-        foreach($aPermissions as $sPermissions => $aFiles) {
-        	$sCheckFunction = 'is' . ucfirst($sPermissions);
-            foreach($aFiles as $sFile) {
-            	$sPath = bx_ltrim_str($this->_sModulePath . $sFile, BX_DIRECTORY_PATH_ROOT);
-            	if(BxDolInstallerUtils::$sCheckFunction($sPath))
-            		continue;
-
-            	if(!$oFile->setPermissions($sPath, $sPermissions))
-                    $aResult[] = array('path' => $this->_sModulePath . $sFile, 'permissions' => $sPermissions);
-            }
-        }
+		$aResult = array();
+        foreach($aChangeItems as $aChangeItem)
+			if(!$oFile->setPermissions($aChangeItem['path'], $aChangeItem['permissions']))
+				$aResult[] = array('path' => $this->_sModulePath . $aChangeItem['file'], 'permissions' => $aChangeItem['permissions']);
 
         return empty($aResult) ? BX_DOL_STUDIO_INSTALLER_SUCCESS : array('code' => BX_DOL_STUDIO_INSTALLER_FAILED, 'content' => $aResult);
     }
@@ -606,43 +613,10 @@ class BxDolStudioInstaller extends BxDolInstallerUtils {
                 break;
         }
 
-        $sPath = $this->_sHomePath . 'install/sql/' . $sOperation . '.sql';
-        if(!file_exists($sPath) || !($rHandler = fopen($sPath, "r")))
-            return BX_DOL_STUDIO_INSTALLER_FAILED;
-
-        $sQuery = "";
-        $sDelimiter = ';';
-        $aResult = array();
-        while(!feof($rHandler)) {
-            $sStr = trim(fgets($rHandler));
-
-            if(empty($sStr) || $sStr[0] == "" || $sStr[0] == "#" || ($sStr[0] == "-" && $sStr[1] == "-"))
-                continue;
-
-            //--- Change delimiter ---//
-            if(strpos($sStr, "DELIMITER //") !== false || strpos($sStr, "DELIMITER ;") !== false) {
-                $sDelimiter = trim(str_replace('DELIMITER', '', $sStr));
-                continue;
-            }
-
-            $sQuery .= $sStr;
+        bx_import('BxDolDb');
+        $mixedResult = BxDolDb::getInstance()->executeSQL($this->_sHomePath . 'install/sql/' . $sOperation . '.sql');
 
-            //--- Check for multiline query ---//
-            if(substr($sStr, -strlen($sDelimiter)) != $sDelimiter)
-                continue;
-
-            //--- Execute query ---//
-            if($sDelimiter != ';')
-                $sQuery = str_replace($sDelimiter, "", $sQuery);
-            $rResult = db_res(trim($sQuery), false);
-            if(!$rResult)
-                $aResult[] = array('query' => $sQuery, 'error' => BxDolDb::getInstance()->getErrorMessage());
-
-            $sQuery = "";
-        }
-        fclose($rHandler);
-
-        return empty($aResult) ? BX_DOL_STUDIO_INSTALLER_SUCCESS : array('code' => BX_DOL_STUDIO_INSTALLER_FAILED, 'content' => $aResult);
+        return $mixedResult === true ? BX_DOL_STUDIO_INSTALLER_SUCCESS : array('code' => BX_DOL_STUDIO_INSTALLER_FAILED, 'content' => $mixedResult);
     }
     function actionExecuteSqlFailed($mixedResult) {
         $sResult = '<br />' . _t('_adm_err_modules_wrong_mysql_query') . '<br />';

+ 18 - 4
studio/classes/BxDolStudioSettings.php

@@ -67,17 +67,31 @@ class BxDolStudioSettings extends BxTemplStudioPage {
 
         foreach ($aCategories as $sCategory) {
             $aOptions = array();
-            $iOptions = $this->oDb->getOptions(array('type' => 'by_category_name', 'value' => $sCategory), $aOptions);
+            $iOptions = $this->oDb->getOptions(array('type' => 'by_category_name_full', 'value' => $sCategory), $aOptions);
 
             $aData = array();
             foreach($aOptions as $aOption) {
                 $aData[$aOption['name']] = $oForm->getCleanValue($aOption['name']);
 
                 if(!empty($aOption['check'])) {
-                    $oFunction = create_function('$arg0', $aOption['check']);
-                    if(!$oFunction($aData[$aOption['name']])) {
+                	$sCheckerHelper = '';
+                	if(!empty($aOption['type_name']) && BxDolRequest::serviceExists($aOption['type_name'], 'get_settings_checker_helper'))
+                		$sCheckerHelper = BxDolService::call($aOption['type_name'], 'get_settings_checker_helper');
+
+                	if($sCheckerHelper == '') {
+                		bx_import('BxDolStudioForm');
+                		$sCheckerHelper = 'BxDolStudioFormCheckerHelper';
+                	}
+
+                	$oChecker = new $sCheckerHelper();
+                	$aCheckFunction = array($oChecker, 'check' . bx_gen_method_name($aOption['check']));
+                	$aCheckFunctionParams = array($aData[$aOption['name']]);
+                	if(!empty($aOption['check_params']))
+                		$aCheckFunctionParams = array_merge($aCheckFunctionParams, unserialize($aOption['check_params']));
+
+                	if(is_callable($aCheckFunction) && !call_user_func_array($aCheckFunction, $aCheckFunctionParams)) {
                         $this->sCategory = $sCategory;
-                        return $this->getJsResult("'" . $aOption['title'] .  "' " . $aOption['check_error'], false);
+                        return $this->getJsResult(_t('_adm_stg_err_save_error_message', _t($aOption['caption']), _t($aOption['check_error'])), false);
                     }
                 }
 

+ 7 - 1
studio/classes/BxDolStudioSettingsQuery.php

@@ -126,6 +126,11 @@ class BxDolStudioSettingsQuery extends BxDolStudioPageQuery {
             case 'by_category_name':
                 $sJoinClause .= "LEFT JOIN `sys_options_categories` AS `tc` ON `to`.`category_id`=`tc`.`id` ";
                 $sWhereClause .= $this->prepare("AND `tc`.`name`=?", $aParams['value']);
+                break;
+			case 'by_category_name_full':
+				$sSelectClause .= ", `tc`.`name` AS `category_name`, `tt`.`name` AS `type_name`";
+				$sJoinClause .= "LEFT JOIN `sys_options_categories` AS `tc` ON `to`.`category_id`=`tc`.`id` LEFT JOIN `sys_options_types` AS `tt` ON `tc`.`type_id`=`tt`.`id` ";
+                $sWhereClause .= $this->prepare("AND `tc`.`name`=?", $aParams['value']);
                 break;
         }
 
@@ -138,8 +143,9 @@ class BxDolStudioSettingsQuery extends BxDolStudioPageQuery {
                 `to`.`type` AS `type`,
                 `to`.`extra` AS `extra`,
                 `to`.`check` AS `check`,
+                `to`.`check_params` AS `check_params`,
                 `to`.`check_error` AS `check_error`,
-                `to`.`order` AS `order` " . $sSelectClause . "
+                `to`.`order` AS `order`" . $sSelectClause . "
             FROM `sys_options` AS `to` " . $sJoinClause . "
             WHERE 1 " . $sWhereClause . " " . $sOrderClause . " " . $sLimitClause;
         $aItems = call_user_func_array(array($this, $aMethod['name']), $aMethod['params']);

+ 1 - 1
studio/template/css/dashboard.css

@@ -11,7 +11,7 @@ div.bx-dbd-virsion-image {
 div.bx-dbd-virsion-info {
 	position: relative;
 	min-height: 110px;
-	margin-left: 120px;
+	margin-left: 130px;
 }
 div.bx-dbd-vi-column {
 	position: relative;

+ 11 - 9
studio/template/scripts/BxBaseStudioNavigationMenus.php

@@ -465,15 +465,17 @@ class BxBaseStudioNavigationMenus extends BxDolStudioNavigationMenus {
     }
 
     protected function _getCellItems ($mixedValue, $sKey, $aField, $aRow) {
-        $aSets = array();
-        $this->oDb->getSets(array('type' => 'by_name', 'value' => $aRow['set_name']), $aSets, false);
-
-        $mixedValue = $this->_oTemplate->parseHtmlByName('bx_a.html', array(
-            'href' => sprintf($this->sUrlViewItems, $aRow['module'], $aRow['set_name']),
-            'title' => _t('_adm_nav_txt_manage_items'),
-        	'bx_repeat:attrs' => array(),
-            'content' => _t('_adm_nav_txt_n_items', $aSets['items_count'])
-        ));
+    	if(!empty($aRow['set_name'])) {
+	        $aSets = array();
+	        $this->oDb->getSets(array('type' => 'by_name', 'value' => $aRow['set_name']), $aSets, false);
+
+	        $mixedValue = $this->_oTemplate->parseHtmlByName('bx_a.html', array(
+	            'href' => sprintf($this->sUrlViewItems, $aRow['module'], $aRow['set_name']),
+	            'title' => _t('_adm_nav_txt_manage_items'),
+	        	'bx_repeat:attrs' => array(),
+	            'content' => _t('_adm_nav_txt_n_items', $aSets['items_count'])
+	        ));
+    	}
 
         return parent::_getCellDefault ($mixedValue, $sKey, $aField, $aRow);
     }

+ 0 - 4
studio/template/scripts/BxBaseStudioSettings.php

@@ -202,8 +202,6 @@ class BxBaseStudioSettings extends BxDolStudioSettings {
 
                 if (BxDolService::isSerializedService($aItem['extra']))
                     $aField['values'] = BxDolService::callSerialized($aItem['extra']);
-                elseif (substr($aItem['extra'], 0, 4) == 'PHP:') // TODO: get rid of PHP: values and replace it with serialized string
-                    $aField['values'] = eval(substr($aItem['extra'], 4));
                 else
                     foreach(explode(',', $aItem['extra']) as $sValue)
                         $aField['values'][$sValue] = $sValue;
@@ -223,8 +221,6 @@ class BxBaseStudioSettings extends BxDolStudioSettings {
 
                 if (BxDolService::isSerializedService($aItem['extra']))
                     $aField['values'] = BxDolService::callSerialized($aItem['extra']);
-                elseif (substr($aItem['extra'], 0, 4) == 'PHP:') // TODO: get rid of PHP: values and replace it with serialized string
-                    $aField['values'] = eval(substr($aItem['extra'], 4));
                 else
                     foreach(explode(',', $aItem['extra']) as $sValue)
                         $aField['values'][] = array('key' => $sValue, 'value' => $sValue);

+ 25 - 0
template/scripts/BxBaseAclServices.php

@@ -0,0 +1,25 @@
+<?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    DolphinCore Dolphin Core
+ * @{
+ */
+
+/**
+ * System services related to ACL.
+ */
+class BxBaseAclServices extends BxDol {
+    public function __construct() {
+        parent::__construct();
+    }
+
+	public function serviceGetMemberships($bPurchasableOnly = false, $bActiveOnly = false, $isTranslate = true)
+    {
+    	bx_import('BxDolAcl');
+    	return BxDolAcl::getInstance()->getMemberships($bPurchasableOnly, $bActiveOnly, $isTranslate);
+    }
+}
+
+/** @} */

+ 32 - 0
template/scripts/BxBaseImageServices.php

@@ -0,0 +1,32 @@
+<?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    DolphinCore Dolphin Core
+ * @{
+ */
+
+/**
+ * System services related to Images' Processing.
+ */
+class BxBaseImageServices extends BxDol {
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    public function serviceAlertResponseFileDeleteLocal($oAlert, $sObject)
+    {
+    	bx_import('BxDolImageTranscoder'); 
+    	BxDolImageTranscoder::onAlertResponseFileDeleteLocal($oAlert, $sObject);
+    }
+
+	public function serviceAlertResponseFileDeleteOrig($oAlert, $sObject)
+    {
+    	bx_import('BxDolImageTranscoder'); 
+    	BxDolImageTranscoder::onAlertResponseFileDeleteOrig($oAlert, $sObject);
+    }
+}
+
+/** @} */

+ 33 - 0
template/scripts/BxBaseLanguagesServices.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    DolphinCore Dolphin Core
+ * @{
+ */
+
+/**
+ * System services related to Languages.
+ */
+class BxBaseLanguagesServices extends BxDol {
+    public function __construct() {
+        parent::__construct();
+    }
+
+    public function serviceGetLanguages($bIdAsKey = false, $bActiveOnly = false) {
+    	bx_import('BxDolLanguages');
+    	$aValues = BxDolLanguages::getInstance()->getLanguages($bIdAsKey, $bActiveOnly);
+
+    	$aResult = array(); 
+    	foreach($aValues as $sKey => $sValue) 
+    		$aResult[] = array(
+    			'key' => $sKey, 
+    			'value' => $sValue
+    		);
+
+		return $aResult;
+    }
+}
+
+/** @} */

+ 33 - 0
template/scripts/BxBaseTemplateServices.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    DolphinCore Dolphin Core
+ * @{
+ */
+
+/**
+ * System services related to Templates.
+ */
+class BxBaseTemplateServices extends BxDol {
+    public function __construct() {
+        parent::__construct();
+    }
+
+	public function serviceGetTemplates($bEnabledOnly = true, $bShortInfo = true)
+    {
+    	$aValues = get_templates_array($bEnabledOnly, $bShortInfo);
+
+    	$aResult = array(); 
+    	foreach($aValues as $sKey => $sValue) 
+    		$aResult[] = array(
+    			'key' => $sKey, 
+    			'value' => $sValue
+    		);
+
+    	return $aResult;
+    }
+}
+
+/** @} */