Alex Trofimov 12 лет назад
Родитель
Сommit
9d2caf66e3
60 измененных файлов с 2078 добавлено и 1940 удалено
  1. 24 0
      modules/base/general/classes/BxBaseModGeneralConfig.php
  2. 28 0
      modules/base/general/classes/BxBaseModGeneralDb.php
  3. 58 0
      modules/base/general/classes/BxBaseModGeneralFormEntry.php
  4. 188 0
      modules/base/general/classes/BxBaseModGeneralFormsEntryHelper.php
  5. 59 0
      modules/base/general/classes/BxBaseModGeneralMenuView.php
  6. 233 0
      modules/base/general/classes/BxBaseModGeneralModule.php
  7. 59 0
      modules/base/general/classes/BxBaseModGeneralPageEntry.php
  8. 58 0
      modules/base/general/classes/BxBaseModGeneralSearchResult.php
  9. 29 0
      modules/base/general/classes/BxBaseModGeneralTemplate.php
  10. 22 0
      modules/base/profile/classes/BxBaseModProfileConfig.php
  11. 43 0
      modules/base/profile/classes/BxBaseModProfileDb.php
  12. 62 66
      modules/base/profile/classes/BxBaseModProfileFormEntry.php
  13. 113 0
      modules/base/profile/classes/BxBaseModProfileFormsEntryHelper.php
  14. 70 0
      modules/base/profile/classes/BxBaseModProfileMenuView.php
  15. 290 0
      modules/base/profile/classes/BxBaseModProfileModule.php
  16. 18 51
      modules/base/profile/classes/BxBaseModProfilePageEntry.php
  17. 23 0
      modules/base/profile/classes/BxBaseModProfileSearchResult.php
  18. 180 0
      modules/base/profile/classes/BxBaseModProfileTemplate.php
  19. 12 0
      modules/base/profile/template/cover.html
  20. 75 0
      modules/base/profile/template/css/main.css
  21. 6 0
      modules/base/profile/template/image_popup.html
  22. 6 0
      modules/base/profile/template/picture_preview.html
  23. 5 0
      modules/base/profile/template/unit.html
  24. 2 4
      modules/base/text/classes/BxBaseModTextConfig.php
  25. 4 7
      modules/base/text/classes/BxBaseModTextDb.php
  26. 6 19
      modules/base/text/classes/BxBaseModTextFormEntry.php
  27. 47 189
      modules/base/text/classes/BxBaseModTextFormsEntryHelper.php
  28. 2 30
      modules/base/text/classes/BxBaseModTextMenu.php
  29. 24 226
      modules/base/text/classes/BxBaseModTextModule.php
  30. 2 32
      modules/base/text/classes/BxBaseModTextPageEntry.php
  31. 3 36
      modules/base/text/classes/BxBaseModTextSearchResult.php
  32. 2 9
      modules/base/text/classes/BxBaseModTextTemplate.php
  33. 1 1
      modules/base/text/template/attachments.html
  34. 2 2
      modules/boonex/convos/install/sql/enable.sql
  35. 6 0
      modules/boonex/english/data/langs/system.xml
  36. 3 3
      modules/boonex/notes/install/sql/enable.sql
  37. 94 28
      modules/boonex/persons/classes/BxPersonsConfig.php
  38. 2 23
      modules/boonex/persons/classes/BxPersonsDb.php
  39. 29 0
      modules/boonex/persons/classes/BxPersonsFormEntry.php
  40. 25 0
      modules/boonex/persons/classes/BxPersonsFormsEntryHelper.php
  41. 27 0
      modules/boonex/persons/classes/BxPersonsMenuView.php
  42. 0 119
      modules/boonex/persons/classes/BxPersonsMenuViewPerson.php
  43. 6 404
      modules/boonex/persons/classes/BxPersonsModule.php
  44. 27 0
      modules/boonex/persons/classes/BxPersonsPageEntry.php
  45. 0 213
      modules/boonex/persons/classes/BxPersonsProfileForms.php
  46. 66 89
      modules/boonex/persons/classes/BxPersonsSearchResult.php
  47. 7 146
      modules/boonex/persons/classes/BxPersonsTemplate.php
  48. 0 43
      modules/boonex/persons/classes/BxPersonsUploader.php
  49. 3 6
      modules/boonex/persons/install/langs/en.xml
  50. 0 4
      modules/boonex/persons/install/sql/disable.sql
  51. 21 27
      modules/boonex/persons/install/sql/enable.sql
  52. 1 1
      modules/boonex/persons/install/sql/install.sql
  53. 0 30
      modules/boonex/persons/js/forms.js
  54. 0 1
      modules/boonex/persons/template/block_picture.html
  55. 1 12
      modules/boonex/persons/template/cover.html
  56. 1 85
      modules/boonex/persons/template/css/main.css
  57. 0 17
      modules/boonex/persons/template/form_ghost_template.html
  58. 1 6
      modules/boonex/persons/template/image_popup.html
  59. 1 6
      modules/boonex/persons/template/picture_preview.html
  60. 1 5
      modules/boonex/persons/template/unit.html

+ 24 - 0
modules/base/general/classes/BxBaseModGeneralConfig.php

@@ -0,0 +1,24 @@
+<?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    BaseGeneral Base classes for modules
+ * @ingroup     DolphinModules
+ *
+ * @{
+ */
+
+bx_import('BxDolModuleConfig');
+
+class BxBaseModGeneralConfig extends BxDolModuleConfig 
+{
+    public $CNF;
+
+    function __construct($aModule) 
+    {
+        parent::__construct($aModule);
+    }
+}
+
+/** @} */ 

+ 28 - 0
modules/base/general/classes/BxBaseModGeneralDb.php

@@ -0,0 +1,28 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * CC-BY License - http://creativecommons.org/licenses/by/3.0/
+ * 
+ * @defgroup    BaseGeneral Base classes for modules
+ * @ingroup     DolphinModules
+ *
+ * @{
+ */
+
+bx_import('BxDolModuleDb');
+
+/*
+ * Module database queries
+ */
+class BxBaseModGeneralDb extends BxDolModuleDb
+{
+    protected $_oConfig;
+
+    public function __construct(&$oConfig) 
+    {
+        parent::__construct($oConfig);
+        $this->_oConfig = $oConfig;
+    }
+}
+
+/** @} */ 

+ 58 - 0
modules/base/general/classes/BxBaseModGeneralFormEntry.php

@@ -0,0 +1,58 @@
+<?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    BaseGeneral Base classes for modules
+ * @ingroup     DolphinModules
+ *
+ * @{
+ */
+
+bx_import('BxTemplFormView');
+
+/**
+ * Create/edit entry form
+ */
+class BxBaseModGeneralFormEntry extends BxTemplFormView 
+{
+    protected $MODULE;
+
+    protected $_oModule;
+
+    public function __construct($aInfo, $oTemplate = false) 
+    {
+        parent::__construct($aInfo, $oTemplate);
+        
+        $this->_oModule = BxDolModule::getInstance($this->MODULE);
+    }
+
+    public function insert ($aValsToAdd = array(), $isIgnore = false) 
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        if (isset($CNF['FIELD_AUTHOR']) && empty($aValsToAdd[$CNF['FIELD_AUTHOR']]))
+            $aValsToAdd[$CNF['FIELD_AUTHOR']] = bx_get_logged_profile_id ();
+
+        if (isset($CNF['FIELD_ADDED']) && empty($aValsToAdd[$CNF['FIELD_ADDED']]))
+            $aValsToAdd[$CNF['FIELD_ADDED']] = time();
+
+        if (isset($CNF['FIELD_CHANGED']) && empty($aValsToAdd[$CNF['FIELD_CHANGED']]))
+            $aValsToAdd[$CNF['FIELD_CHANGED']] = time();
+
+        return parent::insert ($aValsToAdd, $isIgnore);
+    }
+
+    function update ($iContentId, $aValsToAdd = array(), &$aTrackTextFieldsChanges = null) 
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        if (isset($CNF['FIELD_CHANGED']))
+            $aValsToAdd[$CNF['FIELD_CHANGED']] = time();
+
+        return parent::update ($iContentId, $aValsToAdd, $aTrackTextFieldsChanges);
+    }
+
+}
+
+/** @} */

+ 188 - 0
modules/base/general/classes/BxBaseModGeneralFormsEntryHelper.php

@@ -0,0 +1,188 @@
+<?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    BaseGeneral Base classes for modules
+ * @ingroup     DolphinModules
+ *
+ * @{
+ */
+
+bx_import('BxDolProfileForms');
+bx_import('BxDolForm');
+
+/**
+ * Entry forms helper functions
+ */
+class BxBaseModGeneralFormsEntryHelper extends BxDolProfileForms 
+{
+    protected $_oModule;
+
+    public function __construct($oModule) 
+    {
+        parent::__construct();
+        $this->_oModule = $oModule;
+    }
+
+    public function addDataForm () 
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        // check access
+        if (CHECK_ACTION_RESULT_ALLOWED !== ($sMsg = $this->_oModule->checkAllowedAdd()))
+            return MsgBox($sMsg);
+
+        // check and display form
+        $oForm = BxDolForm::getObjectInstance($CNF['OBJECT_FORM_ENTRY'], $CNF['OBJECT_FORM_ENTRY_DISPLAY_ADD']);
+        if (!$oForm)
+            return MsgBox(_t('_sys_txt_error_occured'));
+
+        $oForm->initChecker(); 
+
+        if (!$oForm->isSubmittedAndValid())
+            return $oForm->getCode();
+
+        // insert data into database
+        $aValsToAdd = array ();        
+        $iContentId = $oForm->insert ($aValsToAdd);
+        if (!$iContentId) {
+            if (!$oForm->isValid())
+                return $oForm->getCode();
+            else
+                return MsgBox(_t('_sys_txt_error_entry_creation'));
+        }
+
+        $sResult = $this->onDataAddAfter ($iContentId); 
+        if ($sResult)
+            return $sResult;
+
+        // perform action 
+        $this->_oModule->checkAllowedAdd(true);
+
+        // redirect 
+        $this->_redirectAndExit('page.php?i=' . $CNF['URI_VIEW_ENTRY'] . '&id=' . $iContentId);
+    }
+
+    public function editDataForm ($iContentId, $sDisplay = false)
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        if (false === $sDisplay) 
+            $sDisplay = $CNF['OBJECT_FORM_ENTRY_DISPLAY_EDIT'];
+
+        // get content data and profile info
+        list ($oProfile, $aContentInfo) = $this->_getProfileAndContentData($iContentId);
+        if (!$aContentInfo)
+            return MsgBox(_t('_sys_txt_error_entry_is_not_defined')); 
+
+        // check access
+        if (CHECK_ACTION_RESULT_ALLOWED !== ($sMsg = $this->_oModule->checkAllowedEdit($aContentInfo)))
+            return MsgBox($sMsg);
+        
+        // check and display form 
+        $oForm = BxDolForm::getObjectInstance($CNF['OBJECT_FORM_ENTRY'], $sDisplay); 
+        if (!$oForm)
+            return MsgBox(_t('_sys_txt_error_occured'));
+
+        $oForm->initChecker($aContentInfo); 
+
+        if (!$oForm->isSubmittedAndValid())
+            return $oForm->getCode();
+
+        // update data in the DB
+        $aTrackTextFieldsChanges = null;
+
+        $this->onDataEditBefore ($aContentInfo[$CNF['FIELD_ID']], $aContentInfo, $aTrackTextFieldsChanges);
+
+        if (!$oForm->update ($aContentInfo[$CNF['FIELD_ID']], array(), $aTrackTextFieldsChanges)) {
+            if (!$oForm->isValid())
+                return $oForm->getCode();
+            else
+                return MsgBox(_t('_sys_txt_error_entry_update')); 
+        }
+
+        $sResult = $this->onDataEditAfter ($aContentInfo[$CNF['FIELD_ID']], $aContentInfo, $aTrackTextFieldsChanges, $oProfile);
+        if ($sResult)
+            return $sResult;
+
+        // perform action
+        $this->_oModule->checkAllowedEdit($aContentInfo, true);
+
+        // redirect 
+        $this->_redirectAndExit('page.php?i=' . $CNF['URI_VIEW_ENTRY'] . '&id=' . $aContentInfo[$CNF['FIELD_ID']]);
+    }
+
+    public function deleteDataForm ($iContentId, $sDisplay = false) 
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        if (false === $sDisplay) 
+            $sDisplay = $CNF['OBJECT_FORM_ENTRY_DISPLAY_DELETE'];
+
+        // get content data and profile info
+        list ($oProfile, $aContentInfo) = $this->_getProfileAndContentData($iContentId);
+        if (!$aContentInfo)
+            return MsgBox(_t('_sys_txt_error_entry_is_not_defined')); 
+
+        // check access
+        if (CHECK_ACTION_RESULT_ALLOWED !== ($sMsg = $this->_oModule->checkAllowedDelete($aContentInfo)))
+            return MsgBox($sMsg);
+        
+        // check and display form 
+        $oForm = BxDolForm::getObjectInstance($CNF['OBJECT_FORM_ENTRY'], $sDisplay);
+        if (!$oForm)
+            return MsgBox(_t('_sys_txt_error_occured'));
+
+        $oForm->initChecker($aContentInfo); 
+
+        if (!$oForm->isSubmittedAndValid())
+            return $oForm->getCode();
+
+        if (!$oForm->delete ($aContentInfo[$CNF['FIELD_ID']], $aContentInfo))
+            return MsgBox(_t('_sys_txt_error_entry_delete'));
+
+        $sResult = $this->onDataDeleteAfter ($aContentInfo[$CNF['FIELD_ID']], $aContentInfo, $oProfile);
+        if ($sResult)
+            return $sResult;
+
+        // perform action
+        $this->_oModule->checkAllowedDelete($aContentInfo, true);
+
+        // create an alert
+        bx_alert($this->_oModule->getName(), 'deleted', $aContentInfo[$CNF['FIELD_ID']]);
+
+        // redirect
+        bx_import('BxDolPermalinks');
+        $this->_redirectAndExit(BxDolPermalinks::getInstance()->permalink($CNF['URL_HOME']));
+    }
+
+    public function viewDataForm ($iContentId, $sDisplay = false) 
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        if (false === $sDisplay) 
+            $sDisplay = $CNF['OBJECT_FORM_ENTRY_DISPLAY_VIEW'];
+
+        // get content data and profile info
+        list ($oProfile, $aContentInfo) = $this->_getProfileAndContentData($iContentId);
+        if (!$aContentInfo)
+            return MsgBox(_t('_sys_txt_error_entry_is_not_defined')); 
+
+        // check access
+        if (CHECK_ACTION_RESULT_ALLOWED !== ($sMsg = $this->_oModule->checkAllowedView($aContentInfo)))
+            return MsgBox($sMsg);
+        
+        // get form 
+        $oForm = BxDolForm::getObjectInstance($CNF['OBJECT_FORM_ENTRY'], $sDisplay);
+        if (!$oForm)
+            return MsgBox(_t('_sys_txt_error_occured'));
+
+        // display profile
+        $oForm->initChecker($aContentInfo);
+        return $oForm->getCode();
+    }
+
+}
+
+/** @} */

+ 59 - 0
modules/base/general/classes/BxBaseModGeneralMenuView.php

@@ -0,0 +1,59 @@
+<?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    BaseGeneral Base classes for modules
+ * @ingroup     DolphinModules
+ *
+ * @{
+ */
+
+bx_import('BxTemplMenu');
+bx_import('BxDolModule');
+
+/**
+ * View entry menu
+ */
+class BxBaseModGeneralMenuView extends BxTemplMenu 
+{
+    protected $MODULE;
+
+    protected $_oModule;
+
+    public function __construct($aObject, $oTemplate = false) 
+    {
+        parent::__construct($aObject, $oTemplate);
+
+        $this->_oModule = BxDolModule::getInstance($this->MODULE);
+    }
+
+    /**
+     * Check if menu items is visible with extended checking linked to "allow*" method of particular module
+     * Associated "allow*" method with particular menu item is stored in module config in MENU_ITEM_TO_METHOD array.
+     * @param $a menu item array
+     * @return boolean
+     */ 
+    protected function _isVisible ($a) 
+    {
+        // default visible settings
+        bx_import('BxDolAcl');
+        if (!BxDolAcl::getInstance()->isMemberLevelInSet($a['visible_for_levels']))
+            return false;
+
+        $CNF = $this->_oModule->_oConfig->CNF;
+
+        // get custom function name to check menu item visibility
+        $sFuncCheckAccess = false;
+        if (isset($CNF['MENU_ITEM_TO_METHOD'][$this->_sObject][$a['name']]))
+            $sFuncCheckAccess = $CNF['MENU_ITEM_TO_METHOD'][$this->_sObject][$a['name']];
+
+        // check custom visibility settings defined in module config class
+        if ($sFuncCheckAccess && CHECK_ACTION_RESULT_ALLOWED !== call_user_func_array(array($this->_oModule, $sFuncCheckAccess), isset($this->_aContentInfo) ? array(&$this->_aContentInfo) : array()))
+            return false;
+
+        return true;
+    }
+}
+
+/** @} */

+ 233 - 0
modules/base/general/classes/BxBaseModGeneralModule.php

@@ -0,0 +1,233 @@
+<?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    BaseGeneral Base classes for modules
+ * @ingroup     DolphinModules
+ *
+ * @{
+ */
+
+bx_import ('BxDolModule');
+
+/**
+ * Base module class.
+ */
+class BxBaseModGeneralModule extends BxDolModule
+{
+    protected $_iProfileId;
+
+    function __construct(&$aModule) 
+    {
+        parent::__construct($aModule);
+        $this->_iProfileId = bx_get_logged_profile_id();
+    }
+
+    // ====== ACTIONS METHODS
+
+    public function actionRss ($sMode = '')
+    {
+        $aArgs = func_get_args();
+        $sMode = array_shift($aArgs);
+
+        if (CHECK_ACTION_RESULT_ALLOWED !== ($sMsg = $this->checkAllowedBrowse())) {
+            $this->_oTemplate->displayAccessDenied ();
+            exit;
+        }
+    
+        $aParams = $this->_buildRssParams($sMode, $aArgs);
+
+        bx_import ('SearchResult', $this->_aModule);
+        $sClass = $this->_aModule['class_prefix'] . 'SearchResult';
+        $o = new $sClass($sMode, $aParams);
+
+        if ($o->isError) {
+            $this->_oTemplate->displayPageNotFound ();
+            exit;
+        }
+
+        $o->outputRSS();
+        exit;
+    }
+
+    // ====== SERVICE METHODS
+
+    /**
+     * Add entry form
+     * @return HTML string
+     */
+    public function serviceEntityCreate () 
+    {
+        bx_import('FormsEntryHelper', $this->_aModule);
+        $sClass = $this->_aModule['class_prefix'] . 'FormsEntryHelper';
+        $oFormsHelper = new $sClass($this);
+        return $oFormsHelper->addDataForm();
+    }
+
+    public function serviceEntityEdit ($iContentId = 0) 
+    {
+        return $this->_serviceEntityForm ('editDataForm', $iContentId);
+    }
+
+    public function serviceEntityDelete ($iContentId = 0) 
+    {
+        return $this->_serviceEntityForm ('deleteDataForm', $iContentId);
+    }
+
+    public function serviceEntityInfo ($iContentId = 0) 
+    {
+        return $this->_serviceEntityForm ('viewDataForm', $iContentId);
+    }
+
+    /**
+     * Entry actions block
+     */
+    public function serviceEntityActions ($iContentId = 0) 
+    {
+        if (!$iContentId)
+            $iContentId = bx_process_input(bx_get('id'), BX_DATA_INT);
+        if (!$iContentId)
+            return false;
+
+        bx_import('BxTemplMenu');
+        $oMenu = BxTemplMenu::getObjectInstance($this->_oConfig->CNF['OBJECT_MENU_ACTIONS_VIEW_ENTRY']);
+        return $oMenu ? $oMenu->getCode() : false;
+    }
+
+    // ====== PERMISSION METHODS
+
+    /**
+     * @return CHECK_ACTION_RESULT_ALLOWED if access is granted or error message if access is forbidden. So make sure to make "true === " checking.
+     */
+    public function checkAllowedBrowse () 
+    {
+        return CHECK_ACTION_RESULT_ALLOWED;
+    }
+
+    /**
+     * @return CHECK_ACTION_RESULT_ALLOWED if access is granted or error message if access is forbidden. So make sure to make strict(===) checking.
+     */
+    public function checkAllowedView ($aDataEntry, $isPerformAction = false) 
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        // moderator and owner always have access
+        if ($aDataEntry[$CNF['FIELD_AUTHOR']] == $this->_iProfileId || $this->_isModerator($isPerformAction))
+            return CHECK_ACTION_RESULT_ALLOWED;
+
+        // check ACL
+        $aCheck = checkActionModule($this->_iProfileId, 'view entry', $this->getName(), $isPerformAction);
+        if ($aCheck[CHECK_ACTION_RESULT] !== CHECK_ACTION_RESULT_ALLOWED)
+            return $aCheck[CHECK_ACTION_MESSAGE];
+
+        // check privacy 
+        if (!empty($CNF['OBJECT_PRIVACY_VIEW'])) {
+        	bx_import('BxDolPrivacy');
+        	$oPrivacy = BxDolPrivacy::getObjectInstance($CNF['OBJECT_PRIVACY_VIEW']);
+		    if ($oPrivacy && !$oPrivacy->check($aDataEntry[$CNF['FIELD_ID']]))
+                return _t('_sys_access_denied_to_private_content');
+        }
+
+        return CHECK_ACTION_RESULT_ALLOWED;
+    }
+
+    /**
+     * @return CHECK_ACTION_RESULT_ALLOWED if access is granted or error message if access is forbidden. So make sure to make strict(===) checking.
+     */
+    public function checkAllowedAdd ($isPerformAction = false) 
+    {
+        // check ACL
+        $aCheck = checkActionModule($this->_iProfileId, 'create entry', $this->getName(), $isPerformAction);
+        if ($aCheck[CHECK_ACTION_RESULT] !== CHECK_ACTION_RESULT_ALLOWED)
+            return $aCheck[CHECK_ACTION_MESSAGE];
+        return CHECK_ACTION_RESULT_ALLOWED;
+    }
+
+    /**
+     * @return CHECK_ACTION_RESULT_ALLOWED if access is granted or error message if access is forbidden. So make sure to make strict(===) checking.
+     */
+    public function checkAllowedEdit ($aDataEntry, $isPerformAction = false) 
+    {
+        // moderator and owner always have access
+        if ($aDataEntry[$this->_oConfig->CNF['FIELD_AUTHOR']] == $this->_iProfileId || $this->_isModerator($isPerformAction))
+            return CHECK_ACTION_RESULT_ALLOWED;
+        return _t('_sys_txt_access_denied');
+    }
+
+    /**
+     * @return CHECK_ACTION_RESULT_ALLOWED if access is granted or error message if access is forbidden. So make sure to make strict(===) checking.
+     */
+    public function checkAllowedDelete (&$aDataEntry, $isPerformAction = false) 
+    {
+        // moderator always has access
+        if ($this->_isModerator($isPerformAction))
+            return CHECK_ACTION_RESULT_ALLOWED;
+
+        // check ACL
+        $aCheck = checkActionModule($this->_iProfileId, 'delete entry', $this->getName(), $isPerformAction);
+        if ($aDataEntry[$this->_oConfig->CNF['FIELD_AUTHOR']] == $this->_iProfileId && $aCheck[CHECK_ACTION_RESULT] === CHECK_ACTION_RESULT_ALLOWED)
+            return CHECK_ACTION_RESULT_ALLOWED;
+
+        return _t('_sys_txt_access_denied');
+    }
+
+    // ====== PROTECTED METHODS
+
+    protected function _serviceBrowse ($sMode, $aParams = false, $iDesignBox = BX_DB_PADDING_DEF, $bDisplayEmptyMsg = false) 
+    {
+        if (CHECK_ACTION_RESULT_ALLOWED !== ($sMsg = $this->checkAllowedBrowse()))
+            return MsgBox($sMsg);
+
+        bx_import('SearchResult', $this->_aModule);
+        $sClass = $this->_aModule['class_prefix'] . 'SearchResult';        
+        $o = new $sClass($sMode, $aParams);
+        
+        $o->setDesignBoxTemplateId($iDesignBox);
+        $o->setDisplayEmptyMsg($bDisplayEmptyMsg);
+
+        if ($o->isError)
+            return '';
+
+        if ($s = $o->processing())
+            return $s;
+        else
+            return '';
+    }
+
+    protected function _isModerator ($isPerformAction = false) 
+    {
+        // check moderator ACL
+        $aCheck = checkActionModule($this->_iProfileId, 'edit any entry', $this->getName(), $isPerformAction); 
+        return $aCheck[CHECK_ACTION_RESULT] === CHECK_ACTION_RESULT_ALLOWED;
+    }
+
+    protected function _serviceEntityForm ($sFormMethod, $iContentId = 0, $sDisplay = false) 
+    {
+        if (!$iContentId)
+            $iContentId = bx_process_input(bx_get('id'), BX_DATA_INT);
+        if (!$iContentId)
+            return false;
+
+        bx_import('FormsEntryHelper', $this->_aModule);
+        $sClass = $this->_aModule['class_prefix'] . 'FormsEntryHelper';
+        $oFormsHelper = new $sClass($this);
+        return $oFormsHelper->$sFormMethod((int)$iContentId, $sDisplay);
+    }
+
+    protected function _serviceTemplateFunc ($sFunc, $iContentId) 
+    {
+        if (!$iContentId)
+            $iContentId = bx_process_input(bx_get('id'), BX_DATA_INT);
+        if (!$iContentId)
+            return false;
+
+        $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
+        if (!$aContentInfo)
+            return false;        
+
+        return $this->_oTemplate->$sFunc($aContentInfo);
+    }
+}
+
+/** @} */ 

+ 59 - 0
modules/base/general/classes/BxBaseModGeneralPageEntry.php

@@ -0,0 +1,59 @@
+<?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    BaseGeneral Base classes for modules
+ * @ingroup     DolphinModules
+ *
+ * @{
+ */
+
+bx_import('BxTemplPage');
+
+/**
+ * Entry create/edit pages
+ */
+class BxBaseModGeneralPageEntry extends BxTemplPage 
+{    
+    protected $MODULE;
+
+    protected $_oModule;
+    protected $_aContentInfo = false;
+
+    public function __construct($aObject, $oTemplate = false) 
+    {
+        parent::__construct($aObject, $oTemplate);
+        $this->_oModule = BxDolModule::getInstance($this->MODULE);
+    }
+
+    public function getCode () 
+    {
+        if (!$this->_aContentInfo) { // if entry is not found - display standard "404 page not found" page
+            $this->_oTemplate->displayPageNotFound();
+            exit;
+        }
+
+        if (CHECK_ACTION_RESULT_ALLOWED !== ($sMsg = $this->_oModule->checkAllowedView($this->_aContentInfo))) {
+			$this->_oTemplate->displayAccessDenied($sMsg);
+            exit;
+        }
+        $this->_oModule->checkAllowedView($this->_aContentInfo, true);
+
+        if (!empty($CNF['OBJECT_VIEWS'])) {
+            bx_import('BxDolView');
+	    	BxDolView::getObjectInstance($CNF['OBJECT_VIEWS'], $this->_aContentInfo[$CNF['FIELD_ID']])->doView();
+        }
+
+        return parent::getCode ();
+    }
+
+    protected function _getPageCacheParams () 
+    {
+        if (!$this->_aContentInfo)
+            return '';
+        return $this->_aContentInfo[$this->_oModule->_oConfig->CNF['FIELD_ID']]; // cache is different for every entry
+    }
+}
+
+/** @} */

+ 58 - 0
modules/base/general/classes/BxBaseModGeneralSearchResult.php

@@ -0,0 +1,58 @@
+<?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    BaseGeneral Base classes for modules
+ * @ingroup     DolphinModules
+ *
+ * @{
+ */
+
+bx_import('BxTemplSearchResult');
+
+class BxBaseModGeneralSearchResult extends BxTemplSearchResult 
+{
+    protected $oModule;
+
+    function __construct($sMode = '', $aParams = array())
+    {
+        parent::__construct();
+    }
+
+    function getMain() 
+    {
+        return BxDolModule::getInstance($this->aCurrent['name']);
+    }
+
+    function getRssUnitLink (&$a) 
+    {
+        $CNF = &$this->oModule->_oConfig->CNF;
+
+        bx_import('BxDolPermalinks');
+        return BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=' . $CNF['URI_VIEW_ENTRY'] . '&id=' . $a[$CNF['FIELD_ID']]);
+    }
+
+    function getRssPageUrl () 
+    {
+        if (false === parent::getRssPageUrl())
+            return false;
+
+        bx_import('BxDolPermalinks');
+        $oPermalinks = BxDolPermalinks::getInstance();
+        return BX_DOL_URL_ROOT . $oPermalinks->permalink($this->aCurrent['rss']['link']);
+    }
+
+    function rss () 
+    {        
+        if (!isset($this->aCurrent['rss']))
+            return '';
+
+        $this->aCurrent['paginate']['perPage'] = empty($this->oModule->_oConfig->CNF['PARAM_NUM_RSS']) ? 10 : getParam($this->oModule->_oConfig->CNF['PARAM_NUM_RSS']);
+
+        return parent::rss();
+    }
+}
+
+/** @} */
+

+ 29 - 0
modules/base/general/classes/BxBaseModGeneralTemplate.php

@@ -0,0 +1,29 @@
+<?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    BaseGeneral Base classes for modules
+ * @ingroup     DolphinModules
+ *
+ * @{
+ */
+
+bx_import('BxDolModuleTemplate');
+
+/**
+ * Module representation.
+ */
+class BxBaseModGeneralTemplate extends BxDolModuleTemplate 
+{
+    protected $MODULE;
+
+    function __construct(&$oConfig, &$oDb) 
+    {
+        parent::__construct($oConfig, $oDb);
+        $this->addCss ('main.css');
+    }
+}
+
+/** @} */ 
+

+ 22 - 0
modules/base/profile/classes/BxBaseModProfileConfig.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    BaseProfile Base classes for profile modules
+ * @ingroup     DolphinModules
+ *
+ * @{
+ */
+
+bx_import('BxBaseModGeneralConfig');
+
+class BxBaseModProfileConfig extends BxBaseModGeneralConfig 
+{
+    function __construct($aModule) 
+    {
+        parent::__construct($aModule);
+    }
+}
+
+/** @} */ 

+ 43 - 0
modules/base/profile/classes/BxBaseModProfileDb.php

@@ -0,0 +1,43 @@
+<?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    BaseProfile Base classes for profile modules
+ * @ingroup     DolphinModules
+ *
+ * @{
+ */
+
+bx_import('BxBaseModGeneralDb');
+
+/*
+ * Profile based module database queries
+ */
+class BxBaseModProfileDb extends BxBaseModGeneralDb 
+{
+    public function __construct(&$oConfig) 
+    {
+        parent::__construct($oConfig);
+    }
+
+    public function getContentInfoById ($iContentId) 
+    {
+        $sQuery = $this->prepare ("SELECT `c`.*, `p`.`account_id`, `p`.`id` AS `profile_id`, `p`.`status` AS `profile_status` FROM `" . $this->_oConfig->CNF['TABLE_ENTRIES'] . "` AS `c` INNER JOIN `sys_profiles` AS `p` ON (`p`.`content_id` = `c`.`id` AND `p`.`type` = 'bx_persons') WHERE `c`.`id` = ?", $iContentId);
+        return $this->getRow($sQuery);
+    }
+
+    public function updateContentPictureById($iContentId, $iProfileId, $iPictureId, $sFieldPicture) 
+    {
+        $sQuery = $this->prepare ("UPDATE `" . $this->_oConfig->CNF['TABLE_ENTRIES'] . "` SET `" . $sFieldPicture . "` = ? WHERE `id` = ? AND `author` = ?", $iPictureId, $iContentId, $iProfileId);
+        return $this->res($sQuery);
+    }
+
+    public function searchByTerm($sTerm, $iLimit) 
+    {
+        $sQuery = $this->prepare("SELECT `c`.`id` AS `content_id`, `p`.`account_id`, `p`.`id` AS `profile_id`, `p`.`status` AS `profile_status` FROM `" . $this->_oConfig->CNF['TABLE_ENTRIES'] . "` AS `c` INNER JOIN `sys_profiles` AS `p` ON (`p`.`content_id` = `c`.`id` AND `p`.`type` = 'bx_persons') WHERE `p`.`status` = ? AND `c`.`fullname` LIKE ? ORDER BY `added` DESC LIMIT ?", BX_PROFILE_STATUS_ACTIVE, '%' . $sTerm . '%', (int)$iLimit);
+        return $this->getAll($sQuery);
+    }
+}
+
+/** @} */ 

+ 62 - 66
modules/boonex/persons/classes/BxPersonsFormPerson.php → modules/base/profile/classes/BxBaseModProfileFormEntry.php

@@ -3,61 +3,67 @@
  * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
  * CC-BY License - http://creativecommons.org/licenses/by/3.0/
  *
- * @defgroup    Persons Persons
+ * @defgroup    BaseProfile Base classes for profile modules
  * @ingroup     DolphinModules
  *
  * @{
  */
 
-bx_import('BxTemplFormView');
-bx_import('BxDolProfile');
-bx_import('BxDolStorage');
-bx_import('BxDolImageTranscoder');
+bx_import('BxBaseModGeneralFormEntry');
 
 /**
- * Create/Edit Person Form.
+ * Create/edit profile form.
  */
-class BxPersonsFormPerson extends BxTemplFormView {
+class BxBaseModProfileFormEntry extends BxBaseModGeneralFormEntry 
+{
+    protected $_iAccountProfileId = 0;
+    protected $_aImageFields = array ();
 
-    protected $_oModule;
-    protected $_iAccountProfileId;
-    protected $_aImageFields;
-
-    public function __construct($aInfo, $oTemplate = false) {                
+    public function __construct($aInfo, $oTemplate = false) 
+    {
         parent::__construct($aInfo, $oTemplate);
 
-        $this->_aImageFields = array (
-            BxPersonsConfig::$FIELD_PICTURE => array (
-                'storage_object' => BxPersonsConfig::$OBJECT_STORAGE,
-                'images_transcoder' => BxPersonsConfig::$OBJECT_IMAGES_TRANSCODER_THUMB,
-                'field_preview' => BxPersonsConfig::$FIELD_PICTURE_PREVIEW,
-            ),
-            BxPersonsConfig::$FIELD_COVER => array (
-                'storage_object' => BxPersonsConfig::$OBJECT_STORAGE_COVER,
-                'images_transcoder' => BxPersonsConfig::$OBJECT_IMAGES_TRANSCODER_COVER_THUMB,
-                'field_preview' => BxPersonsConfig::$FIELD_COVER_PREVIEW,
-            ),
-        );
-        $this->_aImageFields[BxPersonsConfig::$FIELD_PICTURE_PREVIEW] = $this->_aImageFields[BxPersonsConfig::$FIELD_PICTURE];
-        $this->_aImageFields[BxPersonsConfig::$FIELD_COVER_PREVIEW] = $this->_aImageFields[BxPersonsConfig::$FIELD_COVER];
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        if (!empty($CNF['FIELD_PICTURE'])) {
+            $this->_aImageFields[$CNF['FIELD_PICTURE']] = array (
+                'storage_object' => $CNF['OBJECT_STORAGE'],
+                'images_transcoder' => $CNF['OBJECT_IMAGES_TRANSCODER_THUMB'],
+                'field_preview' => $CNF['FIELD_PICTURE_PREVIEW'],
+            );
+        }
+
+        if (!empty($CNF['FIELD_COVER'])) {
+            $this->_aImageFields[$CNF['FIELD_COVER']] = array (
+                'storage_object' => $CNF['OBJECT_STORAGE_COVER'],
+                'images_transcoder' => $CNF['OBJECT_IMAGES_TRANSCODER_COVER_THUMB'],
+                'field_preview' => $CNF['FIELD_COVER_PREVIEW'],
+            );
+        }
+
+        if (!empty($CNF['FIELD_PICTURE_PREVIEW']))
+            $this->_aImageFields[$CNF['FIELD_PICTURE_PREVIEW']] = $this->_aImageFields[$CNF['FIELD_PICTURE']];
+
+        if (!empty($CNF['FIELD_COVER_PREVIEW']))
+            $this->_aImageFields[$CNF['FIELD_COVER_PREVIEW']] = $this->_aImageFields[$CNF['FIELD_COVER']];
 
         $oAccountProfile = BxDolProfile::getInstanceAccountProfile();
         if ($oAccountProfile)
             $this->_iAccountProfileId = $oAccountProfile->id();
-
-        $this->_oModule = BxDolModule::getInstance('bx_persons');
     }
 
-    function initChecker ($aValues = array (), $aSpecificValues = array())  {
-
+    function initChecker ($aValues = array (), $aSpecificValues = array())
+    {
         parent::initChecker($aValues, $aSpecificValues);
 
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
         foreach ($this->_aImageFields as $sField => $aVals) {
             if (!isset($this->aInputs[$sField]))
                 continue;
 
-            if ($aValues && !empty($aValues['id'])) 
-                $this->aInputs[$sField]['content_id'] = $aValues['id'];
+            if ($aValues && !empty($aValues[$CNF['FIELD_ID']])) 
+                $this->aInputs[$sField]['content_id'] = $aValues[$CNF['FIELD_ID']];
 
             $sErrorString = '';
             $this->aInputs[$sField]['file_id'] = $this->_processFile ($sField, isset($aValues[$sField]) ? $aValues[$sField] : 0, $sErrorString);
@@ -87,39 +93,41 @@ class BxPersonsFormPerson extends BxTemplFormView {
         }
     }
 
-    public function insert ($aValsToAdd = array(), $isIgnore = false) {
-        $aValsToAdd = array_merge($aValsToAdd, array (
-            BxPersonsConfig::$FIELD_AUTHOR => $this->_iAccountProfileId,
-            BxPersonsConfig::$FIELD_ADDED => time(),
-            BxPersonsConfig::$FIELD_CHANGED => time(),
-        ));
+    public function insert ($aValsToAdd = array(), $isIgnore = false) 
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
         
-        if (isset($this->aInputs[BxPersonsConfig::$FIELD_PICTURE])) {
+        if (!empty($this->aInputs[$CNF['FIELD_PICTURE']])) {
             $aValsToAdd = array_merge($aValsToAdd, array (
-                BxPersonsConfig::$FIELD_PICTURE => $this->aInputs[BxPersonsConfig::$FIELD_PICTURE]['file_id'],
+                $CNF['FIELD_PICTURE'] => $this->aInputs[$CNF['FIELD_PICTURE']]['file_id'],
             ));
         }
 
-        if (isset($this->aInputs[BxPersonsConfig::$FIELD_COVER])) {
+        if (!empty($this->aInputs[$CNF['FIELD_COVER']])) {
             $aValsToAdd = array_merge($aValsToAdd, array (
-                BxPersonsConfig::$FIELD_COVER => $this->aInputs[BxPersonsConfig::$FIELD_COVER]['file_id'],
+                $CNF['FIELD_COVER'] => $this->aInputs[$CNF['FIELD_COVER']]['file_id'],
             ));
         }
 
         return parent::insert ($aValsToAdd, $isIgnore);
     }
 
-    function update ($iContentId, $aValsToAdd = array(), &$aTrackTextFieldsChanges = null) {        
-        $aValsToAdd[BxPersonsConfig::$FIELD_CHANGED] = time();
-        if (isset($this->aInputs[BxPersonsConfig::$FIELD_COVER]))
-            $aValsToAdd[BxPersonsConfig::$FIELD_COVER] = $this->aInputs[BxPersonsConfig::$FIELD_COVER]['file_id'];
-        if (isset($this->aInputs[BxPersonsConfig::$FIELD_PICTURE]))
-            $aValsToAdd[BxPersonsConfig::$FIELD_PICTURE] = $this->aInputs[BxPersonsConfig::$FIELD_PICTURE]['file_id'];
+    function update ($iContentId, $aValsToAdd = array(), &$aTrackTextFieldsChanges = null) 
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        if (!empty($this->aInputs[$CNF['FIELD_COVER']]))
+            $aValsToAdd[$CNF['FIELD_COVER']] = $this->aInputs[$CNF['FIELD_COVER']]['file_id'];
+
+        if (!empty($this->aInputs[$CNF['FIELD_PICTURE']]))
+            $aValsToAdd[$CNF['FIELD_PICTURE']] = $this->aInputs[$CNF['FIELD_PICTURE']]['file_id'];
 
         return parent::update ($iContentId, $aValsToAdd, $aTrackTextFieldsChanges);
     }
 
-    function delete ($iContentId, $aContentInfo = array()) {
+    function delete ($iContentId, $aContentInfo = array()) 
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
 
         foreach ($this->_aImageFields as $sField => $aVals) {
             if (isset($aContentInfo[$sField]) && $aContentInfo[$sField])
@@ -127,12 +135,13 @@ class BxPersonsFormPerson extends BxTemplFormView {
         }
 
         bx_import('BxDolView');
-		BxDolView::getObjectInstance(BxPersonsConfig::$OBJECT_VIEWS, $iContentId)->onObjectDelete();
+		BxDolView::getObjectInstance($CNF['OBJECT_VIEWS'], $iContentId)->onObjectDelete();
 
         return parent::delete($iContentId);
     }
 
-    function _processFile ($sField, $iFileIdOld, &$sErrorString) {
+    function _processFile ($sField, $iFileIdOld, &$sErrorString) 
+    {
         if (empty($_FILES[$sField]['tmp_name']))
             return $iFileIdOld;
 
@@ -152,8 +161,8 @@ class BxPersonsFormPerson extends BxTemplFormView {
         return $iFileId;
     }
 
-    function _deleteFile ($iFileId, $sStorageObject) {
-
+    function _deleteFile ($iFileId, $sStorageObject) 
+    {
         if (!$iFileId)
             return true;
 
@@ -166,19 +175,6 @@ class BxPersonsFormPerson extends BxTemplFormView {
         return $oStorage->deleteFile($iFileId, $this->_iAccountProfileId);
     }
 
-
-    function addCssJs () {
-
-        if (!isset($this->aParams['view_mode']) || !$this->aParams['view_mode']) {
-            if (self::$_isCssJsAdded)
-                return;
-            $this->_oModule->_oTemplate->addJs('forms.js');
-        }
-
-        return parent::addCssJs ();
-    }
-
-
 }
 
 /** @} */

+ 113 - 0
modules/base/profile/classes/BxBaseModProfileFormsEntryHelper.php

@@ -0,0 +1,113 @@
+<?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    BaseProfile Base classes for profile modules
+ * @ingroup     DolphinModules
+ *
+ * @{
+ */
+
+bx_import('BxBaseModGeneralFormsEntryHelper');
+bx_import('BxDolProfile');
+
+/**
+ * Profile forms helper functions
+ */
+class BxBaseModProfileFormsEntryHelper extends BxBaseModGeneralFormsEntryHelper 
+{
+    public function __construct($oModule) 
+    {
+        parent::__construct($oModule);
+    }
+
+    protected function _getProfileAndContentData ($iContentId) 
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        $aContentInfo = array();
+        $oProfile = false;
+
+        $aContentInfo = $this->_oModule->_oDb->getContentInfoById($iContentId);
+        if (!$aContentInfo)
+            return array (false, false);
+
+        $oProfile = BxDolProfile::getInstance($aContentInfo['profile_id']);
+        if (!$oProfile) {
+            bx_import('BxDolProfileUndefined');
+            $oProfile = BxDolProfileUndefined::getInstance();
+        }
+
+        return array ($oProfile, $aContentInfo);
+    }
+
+    protected function onDataDeleteAfter ($iContentId, $aContentInfo, $oProfile) 
+    {
+        // delete profile
+        if (!$oProfile->delete($aContentInfo['profile_id']))
+            return MsgBox(_t('_sys_txt_error_entry_delete')); 
+
+        return '';
+    }
+
+    protected function onDataEditBefore ($iContentId, $aContentInfo, &$aTrackTextFieldsChanges) 
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        list ($oProfile, $aContentInfo) = $this->_getProfileAndContentData($iContentId);
+        $aProfileInfo = $oProfile->getInfo();
+
+        $isAutoApprove = getParam($CNF['PARAM_AUTOAPPROVAL']) ? true : false;
+        if (!$isAutoApprove && BX_PROFILE_STATUS_ACTIVE == $aProfileInfo['status'])
+            $aTrackTextFieldsChanges = array ();
+    }
+
+    protected function onDataEditAfter ($iContentId, $aContentInfo, $aTrackTextFieldsChanges, $oProfile) 
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        $aProfileInfo = $oProfile->getInfo();
+
+        // change profile to 'pending' only if profile is 'active'
+        $isAutoApprove = getParam($CNF['PARAM_AUTOAPPROVAL']) ? true : false;
+        if (!$isAutoApprove && BX_PROFILE_STATUS_ACTIVE == $aProfileInfo['status'] && !empty($aTrackTextFieldsChanges['changed_fields']))
+            $oProfile->disapprove(BX_PROFILE_ACTION_AUTO);
+
+        // create an alert
+        bx_alert($this->_oModule->getName(), 'edited', $aContentInfo[$CNF['FIELD_ID']]); 
+    }
+
+    protected function onDataAddAfter ($iContentId) 
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        // add account and content association
+        $iProfileId = BxDolProfile::add(BX_PROFILE_ACTION_MANUAL, getLoggedId(), $iContentId, BX_PROFILE_STATUS_PENDING, $this->_oModule->getName());
+        $oProfile = BxDolProfile::getInstance($iProfileId);
+
+        // approve profile if auto-approval is enabled and profile status is 'pending'
+        $sStatus = $oProfile->getStatus();
+        $isAutoApprove = getParam($CNF['PARAM_AUTOAPPROVAL']) ? true : false;
+        if ($sStatus == BX_PROFILE_STATUS_PENDING && $isAutoApprove)
+            $oProfile->approve(BX_PROFILE_ACTION_AUTO);
+
+        // set created profile some default membership
+        bx_import('BxDolAcl');
+        $iAclLevel = getParam($CNF['PARAM_DEFAULT_ACL_LEVEL']);
+        BxDolAcl::getInstance()->setMembership($iProfileId, $iAclLevel, 0, true); 
+
+        // alert
+        bx_alert($this->_oModule->getName(), 'added', $iContentId);
+
+        // switch context to the created profile
+        bx_import('BxDolAccount');
+        $oAccount = BxDolAccount::getInstance();
+        $oAccount->updateProfileContext($iProfileId);
+
+        return '';
+    }
+
+}
+
+/** @} */

+ 70 - 0
modules/base/profile/classes/BxBaseModProfileMenuView.php

@@ -0,0 +1,70 @@
+<?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    BaseProfile Base classes for profile modules
+ * @ingroup     DolphinModules
+ *
+ * @{
+ */
+
+bx_import('BxBaseModGeneralMenuView');
+bx_import('BxDolProfile');
+
+/**
+ * View profile entry menu
+ */
+class BxBaseModProfileMenuView extends BxBaseModGeneralMenuView 
+{
+    protected $_oProfile;
+    protected $_aContentInfo;
+    protected $_aProfileInfo;
+
+    public function __construct($aObject, $oTemplate = false) 
+    {
+        parent::__construct($aObject, $oTemplate);
+
+        $CNF = $this->_oModule->_oConfig->CNF;
+
+        $iProfileId = bx_process_input(bx_get('profile_id'), BX_DATA_INT);
+        $iContentId = bx_process_input(bx_get('id'), BX_DATA_INT);
+        if ($iProfileId)
+            $this->_oProfile = BxDolProfile::getInstance($iProfileId);
+        if (!$this->_oProfile && $iContentId)
+            $this->_oProfile = BxDolProfile::getInstanceByContentAndType($iContentId, $this->MODULE);
+
+        if ($this->_oProfile) {
+            $this->_aProfileInfo = $this->_oProfile->getInfo();
+
+            $this->_aContentInfo = $this->_oModule->_oDb->getContentInfoById($this->_aProfileInfo['content_id']);
+
+            $this->addMarkers($this->_aProfileInfo);
+            $this->addMarkers(array('profile_id' => $this->_oProfile->id()));
+
+            if (isLogged()) {
+                bx_import('BxDolConnection');
+                $oConn = BxDolConnection::getObjectInstance('sys_profiles_friends');
+                if ($oConn->isConnectedNotMutual(bx_get_logged_profile_id(), $this->_oProfile->id())) {
+                    $this->addMarkers(array(
+                        'title_add_friend' => _t($CNF['T']['menu_item_title_befriend_sent']), 
+                        'title_remove_friend' => _t($CNF['T']['menu_item_title_unfriend_cancel_request']),
+                    ));
+                } elseif ($oConn->isConnectedNotMutual($this->_oProfile->id(), bx_get_logged_profile_id())) {
+                    $this->addMarkers(array(
+                        'title_add_friend' => _t($CNF['T']['menu_item_title_befriend_confirm']),
+                        'title_remove_friend' => _t($CNF['T']['menu_item_title_unfriend_reject_request']),
+                    ));
+                } else {
+                    $this->addMarkers(array(
+                        'title_add_friend' => _t($CNF['T']['menu_item_title_befriend']),
+                        'title_remove_friend' => _t($CNF['T']['menu_item_title_unfriend']),
+                    ));
+                }
+            }
+        }
+    }
+
+}
+
+/** @} */

+ 290 - 0
modules/base/profile/classes/BxBaseModProfileModule.php

@@ -0,0 +1,290 @@
+<?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    BaseProfile Base classes for profile modules
+ * @ingroup     DolphinModules
+ *
+ * @{
+ */
+
+bx_import ('BxBaseModGeneralModule');
+bx_import ('BxDolAcl');
+
+/**
+ * Base class for profile modules.
+ */
+class BxBaseModProfileModule extends BxBaseModGeneralModule implements iBxDolProfileService 
+{
+    protected $_iAccountId;
+
+    function __construct(&$aModule) 
+    {
+        parent::__construct($aModule);
+        $this->_iAccountId = getLoggedId();
+    }
+
+    // ====== SERVICE METHODS
+
+    public function serviceProfilesSearch ($sTerm, $iLimit) 
+    {
+        $aRet = array();
+        $a = $this->_oDb->searchByTerm($sTerm, $iLimit);
+        foreach ($a as $r)
+            $aRet[] = array ('label' => $this->serviceProfileName($r['content_id']), 'value' => $r['profile_id']);
+        return $aRet;
+    }
+
+    public function serviceProfileUnit ($iContentId) 
+    {
+        return $this->_serviceTemplateFunc('unit', $iContentId);
+    }
+
+    public function serviceProfileAvatar ($iContentId) 
+    {
+        return $this->_serviceTemplateFunc('urlAvatar', $iContentId);
+    }
+
+    public function serviceProfileEditUrl ($iContentId) 
+    {
+        bx_import('BxDolPermalinks');
+        return BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=' . $this->_oConfig->CNF['URI_EDIT_ENTRY'] . '&id=' . $iContentId);
+    }
+
+    public function serviceProfileThumb ($iContentId) 
+    {
+        return $this->_serviceTemplateFunc('thumb', $iContentId);
+    }
+
+    public function serviceProfileIcon ($iContentId) 
+    {
+        return $this->_serviceTemplateFunc('icon', $iContentId);
+    }
+
+    public function serviceProfileName ($iContentId) 
+    {
+        if (!$iContentId)
+            return false;
+        $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
+        if (!$aContentInfo)
+            return false;        
+        return $aContentInfo[$this->_oConfig->CNF['FIELD_NAME']];
+    }
+
+    public function serviceProfileUrl ($iContentId) 
+    {
+        if (!$iContentId)
+            return false;
+        $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
+        if (!$aContentInfo)
+            return false;
+        $CNF = $this->_oConfig->CNF;
+        bx_import('BxDolPermalinks');
+        return BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=' . $CNF['URI_VIEW_ENTRY'] . '&id=' . $aContentInfo[$CNF['FIELD_ID']]);
+    }
+
+    public function serviceBrowseRecentProfiles () 
+    {
+        return $this->_serviceBrowse ('recent');
+    }
+
+    public function serviceBrowseConnections ($iProfileId, $sObjectConnections = 'sys_profiles_friends', $sConnectionsType = 'content', $iMutual = false, $iDesignBox = BX_DB_PADDING_DEF, $iProfileId2 = 0) 
+    {
+        return $this->_serviceBrowse (
+            'connections', 
+            array(
+                'object' => $sObjectConnections,
+                'type' => $sConnectionsType,
+                'mutual' => $iMutual,
+                'profile' => (int)$iProfileId,  
+                'profile2' => (int)$iProfileId2),
+            $iDesignBox
+        );
+    }
+
+    public function serviceEntityEditCover ($iContentId = 0) 
+    {
+        return $this->_serviceEntityForm ('editDataForm', $iContentId, $this->_oConfig->CNF['OBJECT_FORM_ENTRY_DISPLAY_EDIT_COVER']);
+    }
+
+    public function serviceProfileCover ($iContentId = 0) 
+    {
+       if (!$iContentId)
+            $iContentId = bx_process_input(bx_get('id'), BX_DATA_INT);
+        if (!$iContentId)
+            return false;
+
+        $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
+        if (!$aContentInfo)
+            return false;
+
+        return $this->_oTemplate->cover($aContentInfo);
+    }
+
+    public function serviceProfileFriends ($iContentId = 0) 
+    {
+        if (!$iContentId)
+            $iContentId = bx_process_input(bx_get('id'), BX_DATA_INT);
+        if (!$iContentId)
+            return false;
+
+        $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
+        if (!$aContentInfo)
+            return false;
+        
+        return 'TODO: friends here';
+    }
+
+    // ====== PERMISSION METHODS
+
+    /**
+     * @return CHECK_ACTION_RESULT_ALLOWED if access is granted or error message if access is forbidden. 
+     */
+    public function checkAllowedEdit ($aDataEntry, $isPerformAction = false) 
+    {
+        // moderator always has access
+        if ($this->_isModerator($isPerformAction))
+            return CHECK_ACTION_RESULT_ALLOWED;
+
+        // owner (checked by account! not as profile as ususal) always have access
+        bx_import('BxDolProfile');
+        $oProfileAurhor = BxDolProfile::getInstance($aDataEntry[$this->_oConfig->CNF['FIELD_AUTHOR']]);
+        if ($oProfileAurhor->getAccountId() == $this->_iAccountId)
+            return CHECK_ACTION_RESULT_ALLOWED;
+
+        return _t('_sys_txt_access_denied');
+    }
+
+    /**
+     * Check if user can change cover image
+     */
+    public function checkAllowedChangeCover ($aDataEntry, $isPerformAction = false) 
+    {
+        // moderator always has access
+        if ($this->_isModerator($isPerformAction))
+            return CHECK_ACTION_RESULT_ALLOWED;
+
+        // owner (checked by account! not as profile as ususal) always have access
+        bx_import('BxDolProfile');
+        $oProfileAurhor = BxDolProfile::getInstance($aDataEntry[$this->_oConfig->CNF['FIELD_AUTHOR']]);
+        if ($oProfileAurhor->getAccountId() == $this->_iAccountId)
+            return CHECK_ACTION_RESULT_ALLOWED;
+
+        return _t('_sys_txt_access_denied');
+    }
+
+    /**
+     * @return CHECK_ACTION_RESULT_ALLOWED if access is granted or error message if access is forbidden. 
+     */
+    public function checkAllowedDelete (&$aDataEntry, $isPerformAction = false) 
+    {
+        // moderator always has access
+        if ($this->_isModerator($isPerformAction))
+            return CHECK_ACTION_RESULT_ALLOWED;
+
+        // check ACL and owner (checked by account! not as profile as ususal)
+        bx_import('BxDolProfile');
+        $oProfileAurhor = BxDolProfile::getInstance($aDataEntry[$this->_oConfig->CNF['FIELD_AUTHOR']]);
+
+        $aCheck = checkActionModule($this->_iProfileId, 'delete entry', $this->getName(), $isPerformAction);
+        if ($oProfileAurhor->getAccountId() == $this->_iAccountId && $aCheck[CHECK_ACTION_RESULT] === CHECK_ACTION_RESULT_ALLOWED)
+            return CHECK_ACTION_RESULT_ALLOWED;
+
+        return _t('_sys_txt_access_denied');
+    }
+
+    /**
+     * @return CHECK_ACTION_RESULT_ALLOWED if access is granted or error message if access is forbidden. 
+     */
+    public function checkAllowedViewMoreMenu (&$aDataEntry, $isPerformAction = false) 
+    {
+        bx_import('BxTemplMenu');
+        $oMenu = BxTemplMenu::getObjectInstance($this->_oConfig->CNF['OBJECT_MENU_ACTIONS_VIEW_ENTRY_MORE']);
+        if (!$oMenu || !$oMenu->getCode())
+            return _t('_sys_txt_access_denied');
+        return CHECK_ACTION_RESULT_ALLOWED;
+    }
+
+    /**
+     * @return CHECK_ACTION_RESULT_ALLOWED if access is granted or error message if access is forbidden. 
+     */
+    public function checkAllowedFriendAdd (&$aDataEntry, $isPerformAction = false) 
+    {
+        return $this->_checkAllowedConnect ($aDataEntry, $isPerformAction, 'sys_profiles_friends', true, false);
+    }
+
+    /**
+     * @return CHECK_ACTION_RESULT_ALLOWED if access is granted or error message if access is forbidden. 
+     */
+    public function checkAllowedFriendRemove (&$aDataEntry, $isPerformAction = false) 
+    {
+        if (CHECK_ACTION_RESULT_ALLOWED === $this->_checkAllowedConnect ($aDataEntry, $isPerformAction, 'sys_profiles_friends', false, true, true))
+            return CHECK_ACTION_RESULT_ALLOWED;
+        return $this->_checkAllowedConnect ($aDataEntry, $isPerformAction, 'sys_profiles_friends', false, true, false);
+    }
+
+    /**
+     * @return CHECK_ACTION_RESULT_ALLOWED if access is granted or error message if access is forbidden. 
+     */
+    public function checkAllowedSubscribeAdd (&$aDataEntry, $isPerformAction = false) 
+    {
+        return $this->_checkAllowedConnect ($aDataEntry, $isPerformAction, 'sys_profiles_subscriptions', false, false);
+    }
+
+    /**
+     * @return CHECK_ACTION_RESULT_ALLOWED if access is granted or error message if access is forbidden. 
+     */
+    public function checkAllowedSubscribeRemove (&$aDataEntry, $isPerformAction = false) 
+    {
+        return $this->_checkAllowedConnect ($aDataEntry, $isPerformAction, 'sys_profiles_subscriptions', false, true);
+    }
+
+    // ====== PROTECTED METHODS
+
+    protected function _checkAllowedConnect (&$aDataEntry, $isPerformAction, $sObjConnection, $isMutual, $isInvertResult, $isSwap = false) 
+    {
+        if (!$this->_iProfileId)
+            return _t('_sys_txt_access_denied');
+
+        $CNF = &$this->_oConfig->CNF;
+
+        $oProfileAuthor = BxDolProfile::getInstance($aDataEntry[$CNF['FIELD_AUTHOR']]);
+        $oProfile = $oProfileAuthor ? BxDolProfile::getInstanceByContentTypeAccount($aDataEntry[$CNF['FIELD_ID']], $this->_aModule['name'], $oProfileAuthor->getAccountId()) : false;
+        if (!$oProfile || $oProfile->id() == $this->_iProfileId)
+            return _t('_sys_txt_access_denied');
+
+        bx_import('BxDolConnection');
+        $oConn = BxDolConnection::getObjectInstance($sObjConnection);
+        if ($isSwap)
+            $isConnected = $oConn->isConnected($oProfile->id(), $this->_iProfileId, $isMutual);
+        else
+            $isConnected = $oConn->isConnected($this->_iProfileId, $oProfile->id(), $isMutual);
+
+        if ($isInvertResult)
+            $isConnected = !$isConnected;
+
+        return $isConnected ? _t('_sys_txt_access_denied') : CHECK_ACTION_RESULT_ALLOWED;
+    }
+
+    protected function _buildRssParams($sMode, $aArgs) 
+    {
+        $aParams = array ();
+        $sMode = bx_process_input($sMode);
+        switch ($sMode) {
+            case 'connections':                
+                $aParams = array(
+                    'object' => isset($aArgs[0]) ? $aArgs[0] : '', 
+                    'type' => isset($aArgs[1]) ? $aArgs[1] : '', 
+                    'profile' => isset($aArgs[2]) ? (int)$aArgs[2] : 0, 
+                    'mutual' => isset($aArgs[3]) ? (int)$aArgs[3] : 0,
+                    'profile2' => isset($aArgs[4]) ? (int)$aArgs[4] : 0, 
+                );
+                break;
+        }
+
+        return $aParams;
+    }
+}
+
+/** @} */ 

+ 18 - 51
modules/boonex/persons/classes/BxPersonsPageProfile.php → modules/base/profile/classes/BxBaseModProfilePageEntry.php

@@ -3,13 +3,13 @@
  * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
  * CC-BY License - http://creativecommons.org/licenses/by/3.0/
  *
- * @defgroup    Persons Persons
+ * @defgroup    BaseProfile Base classes for profile modules
  * @ingroup     DolphinModules
  *
  * @{
  */
 
-bx_import('BxTemplPage');
+bx_import('BxBaseModGeneralPageEntry');
 bx_import('BxDolModule');
 bx_import('BxDolMenu');
 bx_import('BxDolProfile');
@@ -18,21 +18,18 @@ bx_import('BxDolInformer');
 /**
  * Profile create/edit/delete pages.
  */
-class BxPersonsPageProfile extends BxTemplPage {    
-    
-    protected $_aContentInfo;
+class BxBaseModProfilePageEntry extends BxBaseModGeneralPageEntry 
+{
     protected $_aProfileInfo;
     protected $_oProfile;
     protected $_oProfileAuthor;
 
-    protected $_aMapStatus2LangKey = array (
-        BX_PROFILE_STATUS_PENDING => '_bx_persons_txt_account_pending',
-        BX_PROFILE_STATUS_SUSPENDED => '_bx_persons_txt_account_suspended',
-    );
-
-    public function __construct($aObject, $oTemplate = false) {
+    public function __construct($aObject, $oTemplate = false) 
+    {
         parent::__construct($aObject, $oTemplate);
 
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
         $aInformers = array ();
 
         // get profile info
@@ -43,13 +40,12 @@ class BxPersonsPageProfile extends BxTemplPage {
             $this->_oProfile = BxDolProfile::getInstance($iProfileId);
 
         if (!$this->_oProfile && $iContentId)
-            $this->_oProfile = BxDolProfile::getInstanceByContentAndType($iContentId, 'bx_persons');
+            $this->_oProfile = BxDolProfile::getInstanceByContentAndType($iContentId, $this->MODULE);
 
         if ($this->_oProfile) {
             $this->_aProfileInfo = $this->_oProfile->getInfo();
-            $oModuleMain = BxDolModule::getInstance('bx_persons');
-            $this->_aContentInfo = $oModuleMain->_oDb->getContentInfoById($this->_aProfileInfo['content_id']);
-            $this->_oProfileAuthor = $this->_aContentInfo ? BxDolProfile::getInstance($this->_aContentInfo[BxPersonsConfig::$FIELD_AUTHOR]) : false;
+            $this->_aContentInfo = $this->_oModule->_oDb->getContentInfoById($this->_aProfileInfo['content_id']);
+            $this->_oProfileAuthor = $this->_aContentInfo ? BxDolProfile::getInstance($this->_aContentInfo[$CNF['FIELD_AUTHOR']]) : false;
         }
 
         if (!$this->_aContentInfo || !$this->_oProfile)
@@ -57,7 +53,7 @@ class BxPersonsPageProfile extends BxTemplPage {
 
         // select view profile submenu 
         $oMenuSubmenu = BxDolMenu::getObjectInstance('sys_site_submenu');
-        $oMenuSubmenu->setObjectSubmenu('bx_persons_view_submenu', array (
+        $oMenuSubmenu->setObjectSubmenu($CNF['OBJECT_MENU_SUBMENU_VIEW_ENTRY'], array (
             'title' => $this->_oProfile->getDisplayName(),
             'link' => $this->_oProfile->getUrl(),
             'icon' => $this->_oProfile->getIcon(),
@@ -69,54 +65,25 @@ class BxPersonsPageProfile extends BxTemplPage {
         $this->addMarkers(array('display_name' => $this->_oProfile->getDisplayName())); // profile display name is also suported
 
         // display message if profile isn't active
-        if (bx_get_logged_profile_id() == $this->_oProfileAuthor->id()) { 
+        if (bx_get_logged_profile_id() == $this->_oProfileAuthor->id() && !empty($CNF['INFORMERS']['status'])) { 
             $sStatus = $this->_aContentInfo['profile_status'];
-            if (isset($this->_aMapStatus2LangKey[$sStatus])) {
-                $aInformers[] = array ('name' => 'bx-persons-status-not-active', 'msg' => _t($this->_aMapStatus2LangKey[$sStatus]), 'type' => BX_INFORMER_ALERT);
-            }
+            if (isset($CNF['INFORMERS']['status']['map'][$sStatus]))
+                $aInformers[] = array ('name' => $CNF['INFORMERS']['status']['name'], 'msg' => _t($CNF['INFORMERS']['status']['map'][$sStatus]), 'type' => BX_INFORMER_ALERT);
         }
-/*
-        // display pending connetion requests
-        if (isLogged()) {
-            $aInformer = false;
-            bx_import('BxDolConnection');
-            $oConn = BxDolConnection::getObjectInstance('sys_profiles_friends');
-            if ($oConn->isConnectedNotMutual(bx_get_logged_profile_id(), $this->_oProfile->id()))
-                $aInformer = array ('name' => 'bx-persons-friend-pending-initiator', 'msg' => _t('_bx_persons_txt_friend_pending_initiator'), 'type' => BX_INFORMER_ALERT);
-            elseif ($oConn->isConnectedNotMutual($this->_oProfile->id(), bx_get_logged_profile_id()))
-                $aInformer = array ('name' => 'bx-persons-friend-pending-content', 'msg' => _t('_bx_persons_txt_friend_pending_content'), 'type' => BX_INFORMER_ALERT);
-            if ($aInformer)
-                $aInformers[] = $aInformer;
-        }
-*/
+
         // display message if it is possible to switch to this profile
-        $oProfile = $this->_aContentInfo ? BxDolProfile::getInstanceByContentTypeAccount($this->_aContentInfo['id'], 'bx_persons') : false;
+        $oProfile = $this->_aContentInfo ? BxDolProfile::getInstanceByContentTypeAccount($this->_aContentInfo['id'], $this->MODULE) : false;
         if ($oProfile)
             $oProfile->checkSwitchToProfile($this->_oTemplate);
 
         // add informers
-        if ($aInformers) {            
+        if ($aInformers) {
             $oInformer = BxDolInformer::getInstance($this->_oTemplate);
             if ($oInformer) {
                 foreach ($aInformers as $a)
                     $oInformer->add($a['name'], $this->_replaceMarkers($a['msg']), $a['type']);
             }
         }
-
-		bx_import('BxDolView');
-		BxDolView::getObjectInstance(BxPersonsConfig::$OBJECT_VIEWS, $iContentId)->doView();
-    }
-
-    public function getCode () {
-        if (!$this->_aContentInfo) { // if profile is not found - display standard "404 page not found" page
-            $this->_oTemplate->displayPageNotFound();
-            exit;
-        }
-        return parent::getCode ();
-    }
-
-    protected function _getPageCacheParams () {
-        return $this->_aContentInfo['id']; // cache is different for every account
     }
 
 }

+ 23 - 0
modules/base/profile/classes/BxBaseModProfileSearchResult.php

@@ -0,0 +1,23 @@
+<?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    BaseText Base classes for text modules
+ * @ingroup     DolphinModules
+ *
+ * @{
+ */
+
+bx_import('BxBaseModGeneralSearchResult');
+
+class BxBaseModProfileSearchResult extends BxBaseModGeneralSearchResult 
+{
+    function __construct($sMode = '', $aParams = array()) 
+    {
+        parent::__construct($sMode, $aParams);
+    }
+}
+
+/** @} */
+

+ 180 - 0
modules/base/profile/classes/BxBaseModProfileTemplate.php

@@ -0,0 +1,180 @@
+<?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    BaseProfile Base classes for profile modules
+ * @ingroup     DolphinModules
+ *
+ * @{
+ */
+
+bx_import('BxBaseModGeneralTemplate');
+
+/*
+ * Profile based modules representation.
+ */
+class BxBaseModProfileTemplate extends BxBaseModGeneralTemplate 
+{
+    function __construct(&$oConfig, &$oDb) 
+    {
+        parent::__construct($oConfig, $oDb);
+    }
+
+    /**
+     * Get profile unit
+     */
+    function unit ($aData, $isCheckPrivateContent = true, $sTemplateName = 'unit.html') 
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        // TODO: add privacy checking here
+    
+        // get profile's url
+        bx_import('BxDolPermalinks');
+        $sUrl = BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=' . $CNF['URI_VIEW_ENTRY'] . '&id=' . $aData[$CNF['FIELD_ID']]);
+
+        // generate html
+        $aVars = array (
+            'id' => $aData[$CNF['FIELD_ID']],
+            'thumb_url' => $this->thumb ($aData),
+            'content_url' => $sUrl,
+            'title' => $aData[$CNF['FIELD_NAME']],
+        );
+
+        return $this->parseHtmlByName($sTemplateName, $aVars);
+    }
+
+    /**
+     * Get profile cover
+     */
+    function cover ($aData, $sTemplateName = 'cover.html') 
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        bx_import('BxDolPermalinks');
+
+        $oModule = BxDolModule::getInstance($this->MODULE);
+        $sUrl = BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=' . $CNF['URI_VIEW_ENTRY'] . '&id=' . $aData[$CNF['FIELD_ID']]);
+
+        $sUrlPicture = $this->urlPicture ($aData);
+        $sUrlAvatar = $this->urlAvatar ($aData);
+        $sUrlPictureChange = BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=' . $CNF['URI_EDIT_ENTRY'] . '&id=' . $aData[$CNF['FIELD_ID']]);
+
+        $sUrlCover = $this->urlCover ($aData);
+        $sUrlCoverChange = BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=' . $CNF['URI_EDIT_COVER'] . '&id=' . $aData[$CNF['FIELD_ID']]);        
+
+        $sCoverPopup = '';
+        $sCoverPopupId = $this->MODULE . '-popup-cover';
+        if ($aData[$CNF['FIELD_COVER']]) {
+            bx_import('BxTemplFunctions');
+            $sCoverPopup = BxTemplFunctions::getInstance()->transBox($sCoverPopupId, $this->parseHtmlByName('image_popup.html', array (
+                'image_url' => $sUrlCover,
+                'bx_if:owner' => array (
+                    'condition' => CHECK_ACTION_RESULT_ALLOWED === $oModule->checkAllowedChangeCover($aData),
+                    'content' => array (
+                        'change_image_url' => $sUrlCoverChange,
+                    ),
+                ),
+            )), true, true);
+        }
+
+        $sPicturePopup = '';
+        $sPicturePopupId = $this->MODULE . '-popup-picture';
+        if ($aData[$CNF['FIELD_PICTURE']]) {
+            bx_import('BxTemplFunctions');
+            $sPicturePopup = BxTemplFunctions::getInstance()->transBox($sPicturePopupId, $this->parseHtmlByName('image_popup.html', array (
+                'image_url' => $sUrlPicture,
+                'bx_if:owner' => array (
+                    'condition' => CHECK_ACTION_RESULT_ALLOWED === $oModule->checkAllowedEdit($aData),
+                    'content' => array (
+                        'change_image_url' => $sUrlPictureChange,
+                    ),
+                ),
+            )), true, true);
+        }
+
+        // generate html        
+        $aVars = array (
+            'id' => $aData[$CNF['FIELD_ID']],
+            'content_url' => $sUrl,
+            'title' => $aData[$CNF['FIELD_NAME']],
+
+            'picture_avatar_url' => $sUrlAvatar,
+            'picture_popup' => $sPicturePopup,
+            'picture_popup_id' => $sPicturePopupId,
+            'picture_url' => $sUrlPicture,
+            'picture_href' => !$aData[$CNF['FIELD_PICTURE']] && CHECK_ACTION_RESULT_ALLOWED === $oModule->checkAllowedEdit($aData) ? $sUrlPictureChange : 'javascript:void(0);',            
+
+            'cover_popup' => $sCoverPopup,
+            'cover_popup_id' => $sCoverPopupId,
+            'cover_url' => $sUrlCover,
+            'cover_href' => !$aData[$CNF['FIELD_COVER']] && CHECK_ACTION_RESULT_ALLOWED === $oModule->checkAllowedChangeCover($aData) ? $sUrlCoverChange : 'javascript:void(0);',
+        );
+
+        return $this->parseHtmlByName($sTemplateName, $aVars);
+    }
+
+    /**
+     * Get profile picture thumb url
+     */
+    function thumb ($aData, $bSubstituteNoImage = true) 
+    {
+        $CNF = &$this->_oConfig->CNF;
+        return $this->_image ($CNF['FIELD_PICTURE'], $CNF['OBJECT_IMAGES_TRANSCODER_THUMB'], 'no-picture-thumb.png', $aData, $bSubstituteNoImage);
+    }
+
+    /**
+     * Get profile picture icon url
+     */
+    function icon ($aData, $bSubstituteNoImage = true) 
+    {
+        $CNF = &$this->_oConfig->CNF;
+        return $this->_image ($CNF['FIELD_PICTURE'], $CNF['OBJECT_IMAGES_TRANSCODER_ICON'], 'no-picture-icon.png', $aData, $bSubstituteNoImage);
+    }
+
+    /**
+     * Get profile picture preview url
+     */
+    function urlAvatar ($aData, $bSubstituteNoImage = true) 
+    {
+        $CNF = &$this->_oConfig->CNF;
+        return $this->_image ($CNF['FIELD_PICTURE'], $CNF['OBJECT_IMAGES_TRANSCODER_AVATAR'], 'no-picture-preview.png', $aData, $bSubstituteNoImage);
+    }
+
+    /**
+     * Get profile picture url
+     */
+    function urlPicture ($aData, $bSubstituteNoImage = true) 
+    {
+        $CNF = &$this->_oConfig->CNF;
+        return $this->_image ($CNF['FIELD_PICTURE'], $CNF['OBJECT_IMAGES_TRANSCODER_PICTURE'], 'no-picture-preview.png', $aData, $bSubstituteNoImage);
+    }
+
+    /**
+     * Get profile cover image url
+     */
+    function urlCover ($aData, $bSubstituteNoImage = true) 
+    {
+        $CNF = &$this->_oConfig->CNF;
+        return $this->_image ($CNF['FIELD_COVER'], $CNF['OBJECT_IMAGES_TRANSCODER_COVER'], 'no-picture-cover.png', $aData, $bSubstituteNoImage);
+    }
+
+    /**
+     * Get profile picture icon url
+     */
+    function _image ($sField, $sTranscodeObject, $sNoImage, $aData, $bSubstituteNoImage = true) 
+    {
+        $sImageUrl = false;
+        if ($aData[$sField]) {
+            bx_import('BxDolImageTranscoder');                    
+            $oImagesTranscoder = BxDolImageTranscoder::getObjectInstance($sTranscodeObject);
+            if ($oImagesTranscoder)
+                $sImageUrl = $oImagesTranscoder->getImageUrl($aData[$sField]);
+        }
+        return $bSubstituteNoImage && !$sImageUrl ? $this->getImageUrl($sNoImage) : $sImageUrl;
+    }
+}
+
+/** @} */ 
+

+ 12 - 0
modules/base/profile/template/cover.html

@@ -0,0 +1,12 @@
+
+<div class="bx-base-pofile-cover">
+    <a class="bx-base-pofile-cover-image bx-def-round-corners bx-def-border" href="__cover_href__" onclick="$('#__cover_popup_id__').dolPopupImage('__cover_url__', this)" style="background-image:url(__cover_url__)">&nbsp;</a>
+    <div class="bx-base-pofile-cover-info bx-def-unit bx-def-padding">
+        <a href="__picture_href__" onclick="$('#__picture_popup_id__').dolPopupImage('__picture_url__', $(this).parent())"><img class="bx-def-margin-right bx-def-ava bx-def-ava-size" src="__picture_avatar_url__" /></a>
+        <h1 class="bx-def-unit-info bx-def-margin-sec-bottom bx-def-margin-sec-top bx-def-font-contrasted">__title__</h1>
+    </div>
+</div>
+
+__cover_popup__
+__picture_popup__
+

+ 75 - 0
modules/base/profile/template/css/main.css

@@ -0,0 +1,75 @@
+
+
+/* browse unit */
+
+.bx-base-pofile-unit {
+    width:188px;
+    width:11.8rem;
+    float:left;
+}
+
+.bx-base-pofile-unit div {
+    width:140px;
+    width:8.8rem;
+}
+
+/* profile cover */
+
+.bx-base-pofile-cover {
+    position:relative;
+    height:320px;
+    height:20rem;
+
+    -moz-box-sizing: border-box;
+    -ms-box-sizing: border-box;
+    -webkit-box-sizing: border-box;
+    box-sizing: border-box;
+}
+
+a.bx-base-pofile-cover-image:hover,
+.bx-base-pofile-cover-image {
+    position:absolute;
+    width:100%;
+    height:100%;
+    text-decoration:none;
+
+    background-color: #eee;
+    background-repeat: no-repeat;
+    background-position: center center;
+    -webkit-background-size: cover;
+    -moz-background-size: cover;
+    -o-background-size: cover;
+    background-size: cover;    
+}
+
+.bx-base-pofile-cover-info {
+    position:absolute;
+    bottom:0;
+    left:0;
+}
+
+.bx-base-pofile-cover-info img,
+.bx-base-pofile-cover-info h1 {
+    vertical-align:bottom;
+}
+
+.bx-base-pofile-cover-info img {
+    border:2px solid #fff;
+    border:0.15rem solid #fff;
+}
+
+.bx-base-pofile-cover-info h1.bx-def-unit-info {
+    padding:0;
+    text-shadow: 0px 0px 0.125rem #000;
+    line-height:normal;
+}
+
+.bx-base-pofile-popup-wrapper {
+    position:relative;
+}
+
+.bx-base-pofile-popup-btn {
+    position:absolute;
+    top:0;
+    right:0;
+}

+ 6 - 0
modules/base/profile/template/image_popup.html

@@ -0,0 +1,6 @@
+<div class="bx-base-pofile-popup-wrapper">
+    <bx_if:owner>
+        <div class="bx-base-pofile-popup-btn bx-def-padding"><a class="bx-btn" href="__change_image_url__"><bx_text:_sys_txt_change_image /></a></div>
+    </bx_if:owner>
+    <img class="bx-base-pofile-popup-image" src="__image_url__" />
+</div>

+ 6 - 0
modules/base/profile/template/picture_preview.html

@@ -0,0 +1,6 @@
+<bx_if:picture>
+    <img class="bx-def-round-corners" src="__picture_url__" />
+</bx_if:picture>
+<bx_if:no_picture>
+    <i class="bx-def-font-small"><bx_text:_sys_txt_no_picture_uploaded /></i>
+</bx_if:no_picture>

+ 5 - 0
modules/base/profile/template/unit.html

@@ -0,0 +1,5 @@
+
+<div class="bx-base-pofile-unit bx-def-unit bx-def-margin-bottom bx-def-margin-sec-right">
+    <a href="__content_url__"><img class="bx-def-thumb bx-def-thumb-size" src="__thumb_url__" /></a><div class="bx-def-unit-info bx-def-thumb-size-max-height bx-def-padding-sec-left"><a href="__content_url__">__title__</a></div>
+</div>
+

+ 2 - 4
modules/base/text/classes/BxBaseModTextConfig.php

@@ -9,12 +9,10 @@
  * @{
  */
 
-bx_import('BxDolModuleConfig');
+bx_import('BxBaseModGeneralConfig');
 
-class BxBaseModTextConfig extends BxDolModuleConfig 
+class BxBaseModTextConfig extends BxBaseModGeneralConfig 
 {
-    public $CNF;
-
     function __construct($aModule) 
     {
         parent::__construct($aModule);

+ 4 - 7
modules/base/text/classes/BxBaseModTextDb.php

@@ -9,22 +9,19 @@
  * @{
  */
 
-bx_import('BxDolModuleDb');
+bx_import('BxBaseModGeneralDb');
 
 /*
  * Module database queries
  */
-class BxBaseModTextDb extends BxDolModuleDb
+class BxBaseModTextDb extends BxBaseModGeneralDb
 {
-    protected $_oConfig;
-
-    function __construct(&$oConfig) 
+    public function __construct(&$oConfig) 
     {
         parent::__construct($oConfig);
-        $this->_oConfig = $oConfig;
     }
 
-    function getContentInfoById ($iContentId) 
+    public function getContentInfoById ($iContentId) 
     {
         $sQuery = $this->prepare ("SELECT `c`.* FROM `" . $this->_oConfig->CNF['TABLE_ENTRIES'] . "` AS `c` WHERE `c`.`id` = ?", $iContentId);
         return $this->getRow($sQuery);

+ 6 - 19
modules/base/text/classes/BxBaseModTextFormEntry.php

@@ -9,22 +9,16 @@
  * @{
  */
 
-bx_import('BxTemplFormView');
+bx_import('BxBaseModGeneralFormEntry');
 
 /**
  * Create/Edit entry form
  */
-class BxBaseModTextFormEntry extends BxTemplFormView 
+class BxBaseModTextFormEntry extends BxBaseModGeneralFormEntry
 {
-    protected $MODULE;
-
-    protected $_oModule;
-
     public function __construct($aInfo, $oTemplate = false) 
     {
         parent::__construct($aInfo, $oTemplate);
-        
-        $this->_oModule = BxDolModule::getInstance($this->MODULE);
 
         $CNF = &$this->_oModule->_oConfig->CNF;
 
@@ -92,12 +86,6 @@ class BxBaseModTextFormEntry extends BxTemplFormView
     {
         $CNF = &$this->_oModule->_oConfig->CNF;
 
-        $aValsToAdd[$CNF['FIELD_AUTHOR']] = bx_get_logged_profile_id ();
-        if (isset($CNF['FIELD_ADDED']))
-            $aValsToAdd[$CNF['FIELD_ADDED']] = time();
-        if (isset($CNF['FIELD_CHANGED']))
-            $aValsToAdd[$CNF['FIELD_CHANGED']] = time();
-
         if (CHECK_ACTION_RESULT_ALLOWED === $this->_oModule->checkAllowedSetThumb()) {
             $aThumb = isset($_POST[$CNF['FIELD_THUMB']]) ? bx_process_input ($_POST[$CNF['FIELD_THUMB']], BX_DATA_INT) : false;
             $aValsToAdd[$CNF['FIELD_THUMB']] = 0;
@@ -114,9 +102,6 @@ class BxBaseModTextFormEntry extends BxTemplFormView
     {
         $CNF = &$this->_oModule->_oConfig->CNF;
 
-        if (isset($CNF['FIELD_CHANGED']))
-            $aValsToAdd[$CNF['FIELD_CHANGED']] = time();
-
         if (CHECK_ACTION_RESULT_ALLOWED === $this->_oModule->checkAllowedSetThumb()) {
             $aThumb = bx_process_input ($_POST[$CNF['FIELD_THUMB']], BX_DATA_INT);
             $aValsToAdd[$CNF['FIELD_THUMB']] = 0;
@@ -129,7 +114,7 @@ class BxBaseModTextFormEntry extends BxTemplFormView
         return $iRet;
     }
 
-    function delete ($iContentId) 
+    function delete ($iContentId, $aContentInfo = array()) 
     {
         $CNF = &$this->_oModule->_oConfig->CNF;
 
@@ -145,7 +130,7 @@ class BxBaseModTextFormEntry extends BxTemplFormView
             foreach ($aGhostFiles as $aFile)
                 $this->_deleteFile($aFile['id']);
 
-        // delete db record
+        // delete associated objects data
 
         bx_import('BxDolView');
 		$o = BxDolView::getObjectInstance($CNF['OBJECT_VIEWS'], $iContentId);
@@ -159,6 +144,8 @@ class BxBaseModTextFormEntry extends BxTemplFormView
 		$o = BxDolCmts::getObjectInstance($CNF['OBJECT_COMMENTS'], $iContentId);
         if ($o) $o->onObjectDelete();
 
+        // delete db record
+
         return parent::delete($iContentId);
     }
 

+ 47 - 189
modules/base/text/classes/BxBaseModTextFormsEntryHelper.php

@@ -9,201 +9,17 @@
  * @{
  */
 
-bx_import('BxDolProfileForms');
+bx_import('BxBaseModGeneralFormsEntryHelper');
 bx_import('BxDolProfile');
-bx_import('BxDolForm');
 
 /**
  * Entry forms helper functions
  */
-class BxBaseModTextFormsEntryHelper extends BxDolProfileForms 
+class BxBaseModTextFormsEntryHelper extends BxBaseModGeneralFormsEntryHelper 
 {
-    protected $_oModule;
-
     public function __construct($oModule) 
     {
-        parent::__construct();
-        $this->_oModule = $oModule;
-    }
-
-    /**
-     * @return add data html
-     */
-    public function addDataForm () 
-    {
-        $CNF = &$this->_oModule->_oConfig->CNF;
-
-        // check access
-        if (CHECK_ACTION_RESULT_ALLOWED !== ($sMsg = $this->_oModule->checkAllowedAdd()))
-            return MsgBox($sMsg);
-
-        // check and display form
-        $oForm = BxDolForm::getObjectInstance($CNF['OBJECT_FORM_ENTRY'], $CNF['OBJECT_FORM_ENTRY_DISPLAY_ADD']);
-        if (!$oForm)
-            return MsgBox(_t('_sys_txt_error_occured'));
-
-        $oForm->initChecker(); 
-
-        if (!$oForm->isSubmittedAndValid())
-            return $oForm->getCode();
-
-        // insert data into database
-        $aValsToAdd = array ();        
-        $iContentId = $oForm->insert ($aValsToAdd);
-        if (!$iContentId) {
-            if (!$oForm->isValid())
-                return $oForm->getCode();
-            else
-                return MsgBox(_t('_sys_txt_error_entry_creation'));
-        }
-
-        if (!($aContentInfo = $this->_oModule->_oDb->getContentInfoById($iContentId)))
-            return MsgBox(_t('_sys_txt_error_occured'));
-
-        // perform action 
-        $this->_oModule->checkAllowedAdd(true);
-
-        // alert
-        bx_import('BxDolPrivacy');
-        $aParams = isset($aContentInfo[$CNF['FIELD_ALLOW_VIEW_TO']]) ? array('privacy_view' => $aContentInfo[$CNF['FIELD_ALLOW_VIEW_TO']]) : array();
-        bx_alert($this->_oModule->getName(), 'added', $iContentId, false, $aParams);
-
-        // redirect 
-        $this->_redirectAndExit('page.php?i=' . $CNF['URI_VIEW_ENTRY'] . '&id=' . $iContentId);
-    }
-
-    /**
-     * @return edit data html
-     */
-    public function editDataForm ($iContentId, $sDisplay = false) 
-    {
-        $CNF = &$this->_oModule->_oConfig->CNF;
-
-        if (false === $sDisplay) 
-            $sDisplay = $CNF['OBJECT_FORM_ENTRY_DISPLAY_EDIT'];
-
-        // get content data and profile info
-        list ($oProfile, $aContentInfo) = $this->_getProfileAndContentData($iContentId);
-        if (!$aContentInfo)
-            return MsgBox(_t('_sys_txt_error_entry_is_not_defined')); 
-
-        // check access
-        if (CHECK_ACTION_RESULT_ALLOWED !== ($sMsg = $this->_oModule->checkAllowedEdit($aContentInfo)))
-            return MsgBox($sMsg);
-        
-        // check and display form 
-        $oForm = BxDolForm::getObjectInstance($CNF['OBJECT_FORM_ENTRY'], $sDisplay); 
-        if (!$oForm)
-            return MsgBox(_t('_sys_txt_error_occured'));
-
-        $oForm->initChecker($aContentInfo); 
-
-        if (!$oForm->isSubmittedAndValid())
-            return $oForm->getCode();
-
-        // update data in the DB
-        $aTrackTextFieldsChanges = null;
-        if (!$oForm->update ($aContentInfo[$CNF['FIELD_ID']], array(), $aTrackTextFieldsChanges)) {
-            if (!$oForm->isValid())
-                return $oForm->getCode();
-            else
-                return MsgBox(_t('_sys_txt_error_entry_update')); 
-        }
-
-        if (!($aContentInfo = $this->_oModule->_oDb->getContentInfoById($iContentId)))
-            return MsgBox(_t('_sys_txt_error_occured'));
-
-        // change profile to 'pending' only if profile is 'active'
-        if ($oProfile->isActive() && !empty($aTrackTextFieldsChanges['changed_fields']))
-            $oProfile->disapprove(BX_PROFILE_ACTION_AUTO);
-
-        // perform action
-        $this->_oModule->checkAllowedEdit($aContentInfo, true);
-
-        // create an alert
-        bx_import('BxDolPrivacy');
-        bx_alert($this->_oModule->getName(), 'edited', $aContentInfo[$CNF['FIELD_ID']], false, array('privacy_view' => $aContentInfo[$CNF['FIELD_ALLOW_VIEW_TO']])); 
-
-        // redirect 
-        $this->_redirectAndExit('page.php?i=' . $CNF['URI_VIEW_ENTRY'] . '&id=' . $aContentInfo[$CNF['FIELD_ID']]);
-    }
-
-
-    /**
-     * @return delete data html
-     */
-    public function deleteDataForm ($iContentId, $sDisplay = false) 
-    {
-        $CNF = &$this->_oModule->_oConfig->CNF;
-
-        if (false === $sDisplay) 
-            $sDisplay = $CNF['OBJECT_FORM_ENTRY_DISPLAY_DELETE'];
-
-        // get content data and profile info
-        list ($oProfile, $aContentInfo) = $this->_getProfileAndContentData($iContentId);
-        if (!$aContentInfo)
-            return MsgBox(_t('_sys_txt_error_entry_is_not_defined')); 
-
-        // check access
-        if (CHECK_ACTION_RESULT_ALLOWED !== ($sMsg = $this->_oModule->checkAllowedDelete($aContentInfo)))
-            return MsgBox($sMsg);
-        
-        // check and display form 
-        $oForm = BxDolForm::getObjectInstance($CNF['OBJECT_FORM_ENTRY'], $sDisplay);
-        if (!$oForm)
-            return MsgBox(_t('_sys_txt_error_occured'));
-
-        $oForm->initChecker($aContentInfo); 
-
-        if (!$oForm->isSubmittedAndValid())
-            return $oForm->getCode();
-
-        if (!$oForm->delete ($aContentInfo[$CNF['FIELD_ID']])) {
-            if (!$oForm->isValid())
-                return $oForm->getCode();
-            else
-                return MsgBox(_t('_sys_txt_error_entry_delete'));
-        }
-
-        // perform action
-        $this->_oModule->checkAllowedDelete($aContentInfo, true);
-
-        // create an alert
-        bx_alert($this->_oModule->getName(), 'deleted', $aContentInfo[$CNF['FIELD_ID']]);
-
-        // redirect 
-        bx_import('BxDolPermalinks');
-        $this->_redirectAndExit(BxDolPermalinks::getInstance()->permalink($CNF['URL_HOME']));
-    }
-
-
-    /**
-     * @return view data html
-     */
-    public function viewDataForm ($iContentId) 
-    {
-        $CNF = &$this->_oModule->_oConfig->CNF;
-
-        // get content data and profile info
-        list ($oProfile, $aContentInfo) = $this->_getProfileAndContentData($iContentId);
-        if (!$aContentInfo)
-            return MsgBox(_t('_sys_txt_error_entry_is_not_defined')); 
-
-        // check access
-        if (CHECK_ACTION_RESULT_ALLOWED !== ($sMsg = $this->_oModule->checkAllowedView($aContentInfo)))
-            return MsgBox($sMsg);
-        
-        // get form 
-        $oForm = BxDolForm::getObjectInstance($CNF['OBJECT_FORM_ENTRY'], $CNF['OBJECT_FORM_ENTRY_DISPLAY_VIEW']); 
-        if (!$oForm)
-            return MsgBox(_t('_sys_txt_error_occured'));
-
-        // perform action
-        $this->_oModule->checkAllowedView($aContentInfo);
-
-        // display profile
-        $oForm->initChecker($aContentInfo);
-        return $oForm->getCode();
+        parent::__construct($oModule);
     }
 
     /**
@@ -244,7 +60,7 @@ class BxBaseModTextFormsEntryHelper extends BxDolProfileForms
 
 
     /**
-     * @return array of profile object, profile info and content info
+     * @return array of profile object and content info
      */
     protected function _getProfileAndContentData ($iContentId) 
     {
@@ -252,7 +68,7 @@ class BxBaseModTextFormsEntryHelper extends BxDolProfileForms
 
         $aContentInfo = array();
         $oProfile = false;
-        
+
         $aContentInfo = $this->_oModule->_oDb->getContentInfoById($iContentId);
         if (!$aContentInfo)
             return array (false, false);
@@ -266,6 +82,48 @@ class BxBaseModTextFormsEntryHelper extends BxDolProfileForms
         return array ($oProfile, $aContentInfo);
     }
 
+    protected function onDataDeleteAfter ($iContentId, $aContentInfo, $oProfile) 
+    {
+        return '';
+    }
+
+    protected function onDataEditBefore ($iContentId, $aContentInfo, &$aTrackTextFieldsChanges) 
+    {
+    }
+
+    protected function onDataEditAfter ($iContentId, $aContentInfo, $aTrackTextFieldsChanges, $oProfile) 
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        if (!($aContentInfo = $this->_oModule->_oDb->getContentInfoById($iContentId)))
+            return MsgBox(_t('_sys_txt_error_occured'));
+
+        // change profile to 'pending' only if profile is 'active'
+        if ($oProfile->isActive() && !empty($aTrackTextFieldsChanges['changed_fields']))
+            $oProfile->disapprove(BX_PROFILE_ACTION_AUTO);
+
+        // create an alert
+        bx_import('BxDolPrivacy');
+        bx_alert($this->_oModule->getName(), 'edited', $aContentInfo[$CNF['FIELD_ID']], false, array('privacy_view' => $aContentInfo[$CNF['FIELD_ALLOW_VIEW_TO']])); 
+
+        return '';
+    }
+
+    protected function onDataAddAfter ($iContentId) 
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        if (!($aContentInfo = $this->_oModule->_oDb->getContentInfoById($iContentId)))
+            return MsgBox(_t('_sys_txt_error_occured'));
+
+        // alert
+        bx_import('BxDolPrivacy');
+        $aParams = isset($aContentInfo[$CNF['FIELD_ALLOW_VIEW_TO']]) ? array('privacy_view' => $aContentInfo[$CNF['FIELD_ALLOW_VIEW_TO']]) : array();
+        bx_alert($this->_oModule->getName(), 'added', $iContentId, false, $aParams);
+
+        return '';
+    }
+
 }
 
 /** @} */

+ 2 - 30
modules/base/text/classes/BxBaseModTextMenu.php

@@ -9,48 +9,20 @@
  * @{
  */
 
-bx_import('BxTemplMenu');
+bx_import('BxBaseModGeneralMenuView');
 
 /**
  * General class for module menu.
  */
-class BxBaseModTextMenu extends BxTemplMenu 
+class BxBaseModTextMenu extends BxBaseModGeneralMenuView 
 {
-    protected $MODULE;
-
-    protected $_oModule;
     protected $_aContentInfo;
 
     public function __construct($aObject, $oTemplate = false) 
     {
         parent::__construct($aObject, $oTemplate);
-
-        bx_import('BxDolModule');
-        $this->_oModule = BxDolModule::getInstance($this->MODULE);
     }
 
-    /**
-     * Check if menu items is visible.
-     * @param $a menu item array
-     * @return boolean
-     */ 
-    protected function _isVisible ($a) 
-    {
-        $CNF = $this->_oModule->_oConfig->CNF;
-        $sFuncCheckAccess = false;
-
-        // get custom function name to check menu item visibility
-        if (isset($CNF['MENU_ITEM_TO_METHOD'][$this->_sObject][$a['name']]))
-            $sFuncCheckAccess = $CNF['MENU_ITEM_TO_METHOD'][$this->_sObject][$a['name']];
-
-        // check custom visibility settings defined in module config class
-        if ($sFuncCheckAccess && CHECK_ACTION_RESULT_ALLOWED === call_user_func_array(array($this->_oModule, $sFuncCheckAccess), isset($this->_aContentInfo) ? array(&$this->_aContentInfo) : array()))
-            return true;
-
-        // default visible settings
-        bx_import('BxDolAcl');
-        return BxDolAcl::getInstance()->isMemberLevelInSet($a['visible_for_levels']);
-    }
 }
 
 /** @} */

+ 24 - 226
modules/base/text/classes/BxBaseModTextModule.php

@@ -9,50 +9,17 @@
  * @{
  */
 
-bx_import ('BxDolModule');
+bx_import ('BxBaseModGeneralModule');
 bx_import ('BxDolAcl');
 
 /**
  * Base module class for text based modules
  */
-class BxBaseModTextModule extends BxDolModule
+class BxBaseModTextModule extends BxBaseModGeneralModule
 {
-    protected $_iProfileId;
-
     function __construct(&$aModule) 
     {
         parent::__construct($aModule);
-        $this->_iProfileId = bx_get_logged_profile_id();
-    }
-
-    // ====== ACTIONS METHODS
-
-    public function actionRss ($sMode = '', $sExtra = '') 
-    {
-        if (CHECK_ACTION_RESULT_ALLOWED !== ($sMsg = $this->checkAllowedBrowse())) {
-            $this->_oTemplate->displayAccessDenied ();
-            exit;
-        }
-
-        $aParams = array ();
-        $sMode = bx_process_input($sMode);
-        switch ($sMode) {
-            case 'author':
-                $aParams = array('author' => (int)$sExtra);
-                break;
-        }
-
-        bx_import ('SearchResult', $this->_aModule);
-        $sClass = $this->_aModule['class_prefix'] . 'SearchResult';
-        $o = new $sClass($sMode, $aParams);
-
-        if ($o->isError) {
-            $this->_oTemplate->displayPageNotFound ();
-            exit;
-        }
-
-        $o->outputRSS();
-        exit;
     }
 
     // ====== SERVICE METHODS
@@ -63,7 +30,7 @@ class BxBaseModTextModule extends BxDolModule
      */
     public function serviceBrowsePublic () 
     {
-        return $this->_serviceBrowse ('public');
+        return $this->_serviceBrowse ('public', false, BX_DB_PADDING_DEF, true);
     }
 
     /**
@@ -72,7 +39,7 @@ class BxBaseModTextModule extends BxDolModule
      */
     public function serviceBrowseFeatured () 
     {
-        return $this->_serviceBrowse ('public');
+        return $this->_serviceBrowse ('public', false, BX_DB_PADDING_DEF, true);
     }
 
     /**
@@ -85,53 +52,7 @@ class BxBaseModTextModule extends BxDolModule
             $iProfileId = bx_process_input(bx_get('profile_id'), BX_DATA_INT);
         if (!$iProfileId)
             return '';
-        return $this->_serviceBrowse ('author', array('author' => $iProfileId));
-    }
-
-    /**
-     * Add entry form
-     * @return HTML string
-     */
-    public function serviceEntityCreate () 
-    {
-        bx_import('FormsEntryHelper', $this->_aModule);
-        $sClass = $this->_aModule['class_prefix'] . 'FormsEntryHelper';
-        $oFormsHelper = new $sClass($this);
-        return $oFormsHelper->addDataForm();
-    }
-
-    /**
-     * Edit entry form
-     * @return HTML string
-     */
-    public function serviceEntityEdit ($iContentId = 0) 
-    {
-        return $this->_serviceEntityForm ('editDataForm', $iContentId);
-    }
-
-    /**
-     * Delete entry form
-     * @return HTML string
-     */
-    public function serviceEntityDelete ($iContentId = 0) 
-    {
-        return $this->_serviceEntityForm ('deleteDataForm', $iContentId);
-    }
-
-    /**
-     * Entry text with some additional controls
-     */
-    public function serviceEntityTextBlock ($iContentId = 0) 
-    {
-        return $this->_serviceEntityForm ('viewDataEntry', $iContentId);
-    }
-
-    /**
-     * Additional entry info
-     */
-    public function serviceEntityInfo ($iContentId = 0) 
-    {
-        return $this->_serviceEntityForm ('viewDataForm', $iContentId);
+        return $this->_serviceBrowse ('author', array('author' => $iProfileId), BX_DB_PADDING_DEF, true);
     }
 
     /**
@@ -186,6 +107,14 @@ class BxBaseModTextModule extends BxDolModule
 		//TODO: Rebuild using menus engine when it will be ready for such elements like Vote, Share, etc.
     }
 
+    /**
+     * Entry text with some additional controls
+     */
+    public function serviceEntityTextBlock ($iContentId = 0) 
+    {
+        return $this->_serviceEntityForm ('viewDataEntry', $iContentId);
+    }
+
     /**
      * Entry comments
      */
@@ -208,30 +137,7 @@ class BxBaseModTextModule extends BxDolModule
      */
     public function serviceEntityAuthor ($iContentId = 0) 
     {
-        if (!$iContentId)
-            $iContentId = bx_process_input(bx_get('id'), BX_DATA_INT);
-        if (!$iContentId)
-            return false;
-        $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
-        if (!$aContentInfo)
-            return false;
-
-        return $this->_oTemplate->entryAuthor ($aContentInfo);
-    }
-
-    /**
-     * Entry actions block
-     */
-    public function serviceEntityActions ($iContentId = 0) 
-    {
-        if (!$iContentId)
-            $iContentId = bx_process_input(bx_get('id'), BX_DATA_INT);
-        if (!$iContentId)
-            return false;
-
-        bx_import('BxTemplMenu');
-        $oMenu = BxTemplMenu::getObjectInstance($this->_oConfig->CNF['OBJECT_MENU_ACTIONS_VIEW_ENTRY']);
-        return $oMenu ? $oMenu->getCode() : false;
+        return $this->_serviceTemplateFunc ('entryAuthor', $iContentId);
     }
 
     /**
@@ -239,15 +145,7 @@ class BxBaseModTextModule extends BxDolModule
      */
     public function serviceEntityAttachments ($iContentId = 0)
     {
-        if (!$iContentId)
-            $iContentId = bx_process_input(bx_get('id'), BX_DATA_INT);
-        if (!$iContentId)
-            return false;
-        $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
-        if (!$aContentInfo)
-            return false;
-
-        return $this->_oTemplate->entryAttachments ($aContentInfo);
+        return $this->_serviceTemplateFunc ('entryAttachments', $iContentId);
     }
 
     /**
@@ -354,79 +252,6 @@ class BxBaseModTextModule extends BxDolModule
 
     // ====== PERMISSION METHODS
 
-    /**
-     * @return CHECK_ACTION_RESULT_ALLOWED if access is granted or error message if access is forbidden. So make sure to make strict(===) checking.
-     */
-    public function checkAllowedView ($aDataEntry, $isPerformAction = false) 
-    {
-        $CNF = &$this->_oConfig->CNF;
-
-        // moderator and owner always have access
-        if ($aDataEntry[$CNF['FIELD_AUTHOR']] == $this->_iProfileId || $this->_isModerator($isPerformAction))
-            return CHECK_ACTION_RESULT_ALLOWED;
-
-        // check ACL
-        $aCheck = checkActionModule($this->_iProfileId, 'view entry', $this->getName(), $isPerformAction);
-        if ($aCheck[CHECK_ACTION_RESULT] !== CHECK_ACTION_RESULT_ALLOWED)
-            return $aCheck[CHECK_ACTION_MESSAGE];
-
-        // check privacy 
-    	bx_import('BxDolPrivacy');
-    	$oPrivacy = BxDolPrivacy::getObjectInstance($CNF['OBJECT_PRIVACY_VIEW']);
-		if ($oPrivacy && !$oPrivacy->check($aDataEntry[$CNF['FIELD_ID']]))
-            return _t('_sys_access_denied_to_private_content');
-
-        return CHECK_ACTION_RESULT_ALLOWED;
-    }
-
-    /**
-     * @return CHECK_ACTION_RESULT_ALLOWED if access is granted or error message if access is forbidden. So make sure to make strict(===) checking.
-     */
-    public function checkAllowedBrowse () 
-    {
-        return CHECK_ACTION_RESULT_ALLOWED;
-    }
-
-    /**
-     * @return CHECK_ACTION_RESULT_ALLOWED if access is granted or error message if access is forbidden. So make sure to make strict(===) checking.
-     */
-    public function checkAllowedAdd ($isPerformAction = false) 
-    {
-        // check ACL
-        $aCheck = checkActionModule($this->_iProfileId, 'create entry', $this->getName(), $isPerformAction);
-        if ($aCheck[CHECK_ACTION_RESULT] !== CHECK_ACTION_RESULT_ALLOWED)
-            return $aCheck[CHECK_ACTION_MESSAGE];
-        return CHECK_ACTION_RESULT_ALLOWED;
-    }
-
-    /**
-     * @return CHECK_ACTION_RESULT_ALLOWED if access is granted or error message if access is forbidden. So make sure to make strict(===) checking.
-     */
-    public function checkAllowedEdit ($aDataEntry, $isPerformAction = false) 
-    {
-        // moderator and owner always have access
-        if ($aDataEntry[$this->_oConfig->CNF['FIELD_AUTHOR']] == $this->_iProfileId || $this->_isModerator($isPerformAction))
-            return CHECK_ACTION_RESULT_ALLOWED;
-        return _t('_sys_txt_access_denied');
-    }
-
-    /**
-     * @return CHECK_ACTION_RESULT_ALLOWED if access is granted or error message if access is forbidden. So make sure to make strict(===) checking.
-     */
-    public function checkAllowedDelete (&$aDataEntry, $isPerformAction = false) 
-    {
-        // moderator always has access
-        if ($this->_isModerator($isPerformAction))
-            return CHECK_ACTION_RESULT_ALLOWED;
-
-        // check ACL
-        $aCheck = checkActionModule($this->_iProfileId, 'delete entry', $this->getName(), $isPerformAction);
-        if ($aDataEntry[$this->_oConfig->CNF['FIELD_AUTHOR']] == $this->_iProfileId && $aCheck[CHECK_ACTION_RESULT] === CHECK_ACTION_RESULT_ALLOWED)
-            return CHECK_ACTION_RESULT_ALLOWED;
-
-        return _t('_sys_txt_access_denied');
-    }
-
     /**
      * @return CHECK_ACTION_RESULT_ALLOWED if access is granted or error message if access is forbidden. So make sure to make strict(===) checking.
      */
@@ -441,44 +266,17 @@ class BxBaseModTextModule extends BxDolModule
 
     // ====== PROTECTED METHODS
 
-    protected function _isModerator ($isPerformAction = false) 
-    {
-        // check moderator ACL
-        $aCheck = checkActionModule($this->_iProfileId, 'edit any entry', $this->getName(), $isPerformAction); 
-        return $aCheck[CHECK_ACTION_RESULT] === CHECK_ACTION_RESULT_ALLOWED;
-    }
-
-    protected function _serviceBrowse ($sMode, $aParams = false) 
-    {
-        if (CHECK_ACTION_RESULT_ALLOWED !== ($sMsg = $this->checkAllowedBrowse()))
-            return MsgBox($sMsg);
-
-        $sClass = $this->_aModule['class_prefix'] . 'SearchResult';
-        bx_import('SearchResult', $this->_aModule);
-        $o = new $sClass($sMode, $aParams);
-        
-        $o->setDisplayEmptyMsg(true);
-
-        if ($o->isError)
-            return '';
-
-        if ($s = $o->processing())
-            return $s;
-        else
-            return '';
-    }
-
-    protected function _serviceEntityForm ($sFormMethod, $iContentId = 0) 
+    protected function _buildRssParams($sMode, $aArgs) 
     {
-        if (!$iContentId)
-            $iContentId = bx_process_input(bx_get('id'), BX_DATA_INT);
-        if (!$iContentId)
-            return false;
+        $aParams = array ();
+        $sMode = bx_process_input($sMode);
+        switch ($sMode) {
+            case 'author':
+                $aParams = array('author' => isset($aArgs[0]) ? (int)$aArgs[0] : '');
+                break;
+        }
 
-        bx_import('FormsEntryHelper', $this->_aModule);
-        $sClass = $this->_aModule['class_prefix'] . 'FormsEntryHelper';
-        $oFormsHelper = new $sClass($this);
-        return $oFormsHelper->$sFormMethod((int)$iContentId);
+        return $aParams;
     }
 }
 

+ 2 - 32
modules/base/text/classes/BxBaseModTextPageEntry.php

@@ -9,25 +9,19 @@
  * @{
  */
 
-bx_import('BxTemplPage');
+bx_import('BxBaseModGeneralPageEntry');
 bx_import('BxDolModule');
 bx_import('BxDolMenu');
 
 /**
  * Entry create/edit pages
  */
-class BxBaseModTextPageEntry extends BxTemplPage 
+class BxBaseModTextPageEntry extends BxBaseModGeneralPageEntry 
 {    
-    protected $MODULE;
-
-    protected $_oModule;
-    protected $_aContentInfo = false;
-
     public function __construct($aObject, $oTemplate = false) 
     {
         parent::__construct($aObject, $oTemplate);
 
-        $this->_oModule = BxDolModule::getInstance($this->MODULE);
         $CNF = &$this->_oModule->_oConfig->CNF;
 
         // select view entry submenu
@@ -44,30 +38,6 @@ class BxBaseModTextPageEntry extends BxTemplPage
                 'title' => strmaxtextlen($this->_aContentInfo[$CNF['FIELD_TEXT']], 20, '...'),
             ));
         }
-
-		bx_import('BxDolView');
-		BxDolView::getObjectInstance($CNF['OBJECT_VIEWS'], $iContentId)->doView();
-    }
-
-    public function getCode () 
-    {
-        if (!$this->_aContentInfo) { // if entry is not found - display standard "404 page not found" page
-            $this->_oTemplate->displayPageNotFound();
-            exit;
-        }
-
-        if (CHECK_ACTION_RESULT_ALLOWED !== ($sMsg = $this->_oModule->checkAllowedView($this->_aContentInfo))) {
-			$this->_oTemplate->displayAccessDenied($sMsg);
-            exit;
-        }
-        $this->_oModule->checkAllowedView($this->_aContentInfo, true);
-
-        return parent::getCode ();
-    }
-
-    protected function _getPageCacheParams () 
-    {
-        return $this->_aContentInfo[$this->_oModule->_oConfig->CNF['FIELD_ID']]; // cache is different for every entry
     }
 }
 

+ 3 - 36
modules/base/text/classes/BxBaseModTextSearchResult.php

@@ -9,18 +9,17 @@
  * @{
  */
 
-bx_import('BxTemplSearchResult');
+bx_import('BxBaseModGeneralSearchResult');
 
-class BxBaseModTextSearchResult extends BxTemplSearchResult 
+class BxBaseModTextSearchResult extends BxBaseModGeneralSearchResult 
 {
-    protected $oModule;
     protected $aUnitViews = array('extended' => 'unit.html', 'gallery' => 'unit_gallery.html');
     protected $sUnitViewDefault = 'gallery';
     protected $sUnitViewParamName = 'unit_view';
 
     function __construct($sMode = '', $aParams = array()) 
     {
-        parent::__construct();
+        parent::__construct($sMode, $aParams);
 
         $this->aGetParams = array($this->sUnitViewParamName);
         $this->sUnitTemplate = $this->aUnitViews[$this->sUnitViewDefault];
@@ -28,11 +27,6 @@ class BxBaseModTextSearchResult extends BxTemplSearchResult
             $this->sUnitTemplate = $this->aUnitViews[bx_get($this->sUnitViewParamName)];
     }
 
-    function getMain() 
-    {
-        return BxDolModule::getInstance($this->aCurrent['name']);
-    }
-
     function getDesignBoxMenu () 
     {
         $aMenu = parent::getDesignBoxMenu ();
@@ -46,33 +40,6 @@ class BxBaseModTextSearchResult extends BxTemplSearchResult
         );
     }
 
-    function getRssUnitLink (&$a) 
-    {
-        $CNF = &$this->oModule->_oConfig->CNF;
-
-        bx_import('BxDolPermalinks');
-        return BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=' . $CNF['URI_VIEW_ENTRY'] . '&id=' . $a[$CNF['FIELD_ID']]);
-    }
-
-    function getRssPageUrl () 
-    {
-        if (false === parent::getRssPageUrl())
-            return false;
-
-        bx_import('BxDolPermalinks');
-        $oPermalinks = BxDolPermalinks::getInstance();
-        return BX_DOL_URL_ROOT . $oPermalinks->permalink($this->aCurrent['rss']['link']);
-    }
-
-    function rss () 
-    {        
-        if (!isset($this->aCurrent['rss']))
-            return '';
-
-        $this->aCurrent['paginate']['perPage'] = getParam($this->oModule->_oConfig->CNF['PARAM_NUM_RSS']);
-        return parent::rss();
-    }
-
     function _getPseud () 
     {
         return array(

+ 2 - 9
modules/base/text/classes/BxBaseModTextTemplate.php

@@ -9,23 +9,16 @@
  * @{
  */
 
-bx_import('BxDolModuleTemplate');
+bx_import('BxBaseModGeneralTemplate');
 
 /**
  * Module representation.
  */
-class BxBaseModTextTemplate extends BxDolModuleTemplate 
+class BxBaseModTextTemplate extends BxBaseModGeneralTemplate 
 {
-    protected $MODULE;
-
-    /**
-     * Constructor
-     */
     function __construct(&$oConfig, &$oDb) 
     {
         parent::__construct($oConfig, $oDb);
-
-        $this->addCss ('main.css');
     }
 
     function unit ($aData, $isCheckPrivateContent = true, $sTemplateName = 'unit.html') 

+ 1 - 1
modules/base/text/template/attachments.html

@@ -1,4 +1,4 @@
-<div class="bx-base-text--attachments bx-clearfix">
+<div class="bx-base-text-attachments bx-clearfix">
 
     <bx_repeat:attachments>
         <div class="bx-base-text-attachment bx-def-color-bg-sec bx-def-gal-img-size bx-def-margin-sec-rightbottomleft" style="float:left;">            

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

@@ -77,8 +77,8 @@ INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES
 ('bx_convos_view', 'bx_convos', '_bx_cnv_menu_set_title_view_entry', 0);
 
 INSERT INTO `sys_menu_items`(`set_name`, `module`, `name`, `title_system`, `title`, `link`, `onclick`, `target`, `icon`, `submenu_object`, `visible_for_levels`, `active`, `copyable`, `order`) VALUES 
-('bx_convos_view', 'bx_convos', 'delete-convo', '_bx_cnv_menu_item_title_system_delete_entry', '_bx_cnv_menu_item_title_delete_entry', 'javascript:void(0);', 'bx_cnv_delete(this, \'{content_id}\')', '', 'remove', '', 0, 1, 0, 1),
-('bx_convos_view', 'bx_convos', 'mark-unread-convo', '_bx_cnv_menu_item_title_system_mark_unread_entry', '_bx_cnv_menu_item_title_mark_unread_entry', 'javascript:void(0);', 'bx_cnv_mark_unread(this, \'{content_id}\')', '', 'check', '', 0, 1, 0, 2);
+('bx_convos_view', 'bx_convos', 'delete-convo', '_bx_cnv_menu_item_title_system_delete_entry', '_bx_cnv_menu_item_title_delete_entry', 'javascript:void(0);', 'bx_cnv_delete(this, \'{content_id}\')', '', 'remove', '', 2147483647, 1, 0, 1),
+('bx_convos_view', 'bx_convos', 'mark-unread-convo', '_bx_cnv_menu_item_title_system_mark_unread_entry', '_bx_cnv_menu_item_title_mark_unread_entry', 'javascript:void(0);', 'bx_cnv_mark_unread(this, \'{content_id}\')', '', 'check', '', 2147483647, 1, 0, 2);
 
 
 -- MENU: module sub-menu

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

@@ -1864,6 +1864,7 @@ If it is not enabled then please consider implement this optimization, since it
 	<string name="_sys_txt_account_suspended"><![CDATA[Your account is suspended.]]></string>
 	<string name="_sys_txt_account_unconfirmed"><![CDATA[Your email address is unconfirmed. Please, check your email ({1}) for a confirmation letter and click email confirmation link. Can't find the letter? Check your SPAM folder or <a href="{0}">send the verification letter again</a>.]]></string>
 	<string name="_sys_txt_captcha_not_available"><![CDATA[CAPTCHA not available]]></string>
+    <string name="_sys_txt_change_image"><![CDATA[Change Picure]]></string>
 	<string name="_sys_txt_cmt_loading"><![CDATA[Loading...]]></string>
 	<string name="_sys_txt_confirm_email_already_confirmed"><![CDATA[Your email address is already confirmed.]]></string>
 	<string name="_sys_txt_confirm_email_desc"><![CDATA[Please enter confirmation code which was sent to your email address, or just click confirmation link in the same email message.]]></string>
@@ -1871,7 +1872,10 @@ If it is not enabled then please consider implement this optimization, since it
 	<string name="_sys_txt_confirm_email_sent"><![CDATA[Email verification letter was sent, please check your inbox.]]></string>
 	<string name="_sys_txt_confirm_email_sent_failed"><![CDATA[Error occured, please report error to site administrator.]]></string>
 	<string name="_sys_txt_confirm_email_success"><![CDATA[You email address was successfully confirmed.]]></string>
+    <string name="_sys_txt_current_picture"><![CDATA[Current Picture]]></string>
 	<string name="_sys_txt_data_successfully_submitted"><![CDATA[Done]]></string>
+    <string name="_sys_txt_delete"><![CDATA[Delete]]></string>
+    <string name="_sys_txt_discard"><![CDATA[Discard]]></string>
 	<string name="_sys_txt_empty"><![CDATA[Empty]]></string>
 	<string name="_sys_txt_error_account_creation"><![CDATA[Account creation failed]]></string>
 	<string name="_sys_txt_error_account_delete"><![CDATA[Account delete failed]]></string>
@@ -1899,6 +1903,8 @@ If it is not enabled then please consider implement this optimization, since it
 	<string name="_sys_txt_login_description"><![CDATA[Not a member yet? <a href="{0}">Join now!</a>]]></string>
 	<string name="_sys_txt_login_error"><![CDATA[Entered email or password is incorrect. Please try again.]]></string>
 	<string name="_sys_txt_login_invalid_role"><![CDATA[Access denied]]></string>
+    <string name="_sys_txt_new_picture"><![CDATA[New Picture]]></string>
+    <string name="_sys_txt_no_picture_uploaded"><![CDATA[No picture uploaded]]></string>
 	<string name="_sys_txt_reset_pasword_email_send_failed"><![CDATA[Your new password is <b>{0}</b>, please make sure to save it somewhere becuase we wasn't able to send it to your email. You can change it to any other password after first login.]]></string>
 	<string name="_sys_txt_reset_pasword_email_sent"><![CDATA[Your new password - <b>{0}</b> - was sent to your email. You can change it once you login to your account.]]></string>
 	<string name="_sys_txt_reset_pasword_error_occured"><![CDATA[Error occured, please <a href="{0}">try again</a>.]]></string>

+ 3 - 3
modules/boonex/notes/install/sql/enable.sql

@@ -131,8 +131,8 @@ INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES
 ('bx_notes_view', 'bx_notes', '_bx_notes_menu_set_title_view_entry', 0);
 
 INSERT INTO `sys_menu_items`(`set_name`, `module`, `name`, `title_system`, `title`, `link`, `onclick`, `target`, `icon`, `submenu_object`, `visible_for_levels`, `active`, `copyable`, `order`) VALUES 
-('bx_notes_view', 'bx_notes', 'edit-note', '_bx_notes_menu_item_title_system_edit_entry', '_bx_notes_menu_item_title_edit_entry', 'page.php?i=edit-note&id={content_id}', '', '', 'pencil', '', 0, 1, 0, 1),
-('bx_notes_view', 'bx_notes', 'delete-note', '_bx_notes_menu_item_title_system_delete_entry', '_bx_notes_menu_item_title_delete_entry', 'page.php?i=delete-note&id={content_id}', '', '', 'remove', '', 0, 1, 0, 2);
+('bx_notes_view', 'bx_notes', 'edit-note', '_bx_notes_menu_item_title_system_edit_entry', '_bx_notes_menu_item_title_edit_entry', 'page.php?i=edit-note&id={content_id}', '', '', 'pencil', '', 2147483647, 1, 0, 1),
+('bx_notes_view', 'bx_notes', 'delete-note', '_bx_notes_menu_item_title_system_delete_entry', '_bx_notes_menu_item_title_delete_entry', 'page.php?i=delete-note&id={content_id}', '', '', 'remove', '', 2147483647, 1, 0, 2);
 
 
 -- MENU: actions menu for my entries
@@ -144,7 +144,7 @@ INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES
 ('bx_notes_my', 'bx_notes', '_bx_notes_menu_set_title_entries_my', 0);
 
 INSERT INTO `sys_menu_items`(`set_name`, `module`, `name`, `title_system`, `title`, `link`, `onclick`, `target`, `icon`, `submenu_object`, `visible_for_levels`, `active`, `copyable`, `order`) VALUES 
-('bx_notes_my', 'bx_notes', 'create-note', '_bx_notes_menu_item_title_system_create_entry', '_bx_notes_menu_item_title_create_entry', 'page.php?i=create-note', '', '', 'plus', '', 0, 1, 0, 0);
+('bx_notes_my', 'bx_notes', 'create-note', '_bx_notes_menu_item_title_system_create_entry', '_bx_notes_menu_item_title_create_entry', 'page.php?i=create-note', '', '', 'plus', '', 2147483647, 1, 0, 0);
 
 
 -- MENU: module sub-menu

+ 94 - 28
modules/boonex/persons/classes/BxPersonsConfig.php

@@ -9,35 +9,101 @@
  * @{
  */
 
-bx_import('BxDolModuleConfig');
-
-class BxPersonsConfig extends BxDolModuleConfig {
-
-    public static $FIELD_ID = 'id';
-    public static $FIELD_AUTHOR = 'author';
-    public static $FIELD_ADDED = 'added';
-    public static $FIELD_CHANGED = 'changed';
-    public static $FIELD_NAME = 'fullname';
-    public static $FIELD_PICTURE = 'picture';
-    public static $FIELD_PICTURE_PREVIEW = 'picture_preview';
-    public static $FIELD_COVER = 'cover';
-    public static $FIELD_COVER_PREVIEW = 'cover_preview';
-
-    public static $OBJECT_STORAGE = 'bx_persons_pictures';
-    public static $OBJECT_STORAGE_COVER = 'bx_persons_pictures';
-    public static $OBJECT_IMAGES_TRANSCODER_THUMB = 'bx_persons_thumb';
-    public static $OBJECT_IMAGES_TRANSCODER_ICON = 'bx_persons_icon';
-    public static $OBJECT_IMAGES_TRANSCODER_AVATAR = 'bx_persons_avatar';
-    public static $OBJECT_IMAGES_TRANSCODER_PICTURE = 'bx_persons_picture';
-    public static $OBJECT_IMAGES_TRANSCODER_COVER = 'bx_persons_cover';
-    public static $OBJECT_IMAGES_TRANSCODER_COVER_THUMB = 'bx_persons_cover_thumb';
-	public static $OBJECT_VIEWS = 'bx_persons';
-
-    /**
-     * Constructor
-     */
-    function __construct($aModule) {
+bx_import('BxBaseModProfileConfig');
+
+class BxPersonsConfig extends BxBaseModProfileConfig 
+{
+    function __construct($aModule) 
+    {
         parent::__construct($aModule);
+
+        $aMenuItems2Methods = array (
+            'view-persons-profile' => 'checkAllowedView',
+            'edit-persons-profile' => 'checkAllowedEdit',
+            'delete-persons-profile' => 'checkAllowedDelete',
+            'profile-friend-add' => 'checkAllowedFriendAdd',
+            'profile-friend-remove' => 'checkAllowedFriendRemove',
+            'profile-subscribe-add' => 'checkAllowedSubscribeAdd',
+            'profile-subscribe-remove' => 'checkAllowedSubscribeRemove',
+            'profile-actions-more' => 'checkAllowedViewMoreMenu',
+        );
+
+        $this->CNF = array (
+
+            // database tables
+            'TABLE_ENTRIES' => $aModule['db_prefix'] . 'data',
+
+            // database fields
+            'FIELD_ID' => 'id',
+            'FIELD_AUTHOR' => 'author',
+            'FIELD_ADDED' => 'added',
+            'FIELD_CHANGED' => 'changed',
+            'FIELD_NAME' => 'fullname',
+            'FIELD_PICTURE' => 'picture',
+            'FIELD_PICTURE_PREVIEW' => 'picture_preview',
+            'FIELD_COVER' => 'cover',
+            'FIELD_COVER_PREVIEW' => 'cover_preview',
+
+            // page URIs
+            'URI_VIEW_ENTRY' => 'view-persons-profile',
+            'URI_EDIT_ENTRY' => 'edit-persons-profile',
+            'URI_EDIT_COVER' => 'edit-persons-cover',
+
+            'URL_HOME' => 'member.php',
+
+            // some params
+            'PARAM_AUTOAPPROVAL' => 'bx_persons_autoapproval',
+            'PARAM_DEFAULT_ACL_LEVEL' => 'bx_persons_default_acl_level',
+            'PARAM_NUM_RSS' => '', // TODO:
+
+            // objects
+            'OBJECT_STORAGE' => 'bx_persons_pictures',
+            'OBJECT_STORAGE_COVER' => 'bx_persons_pictures',
+            'OBJECT_IMAGES_TRANSCODER_THUMB' => 'bx_persons_thumb',
+            'OBJECT_IMAGES_TRANSCODER_ICON' => 'bx_persons_icon',
+            'OBJECT_IMAGES_TRANSCODER_AVATAR' => 'bx_persons_avatar',
+            'OBJECT_IMAGES_TRANSCODER_PICTURE' => 'bx_persons_picture',
+            'OBJECT_IMAGES_TRANSCODER_COVER' => 'bx_persons_cover',
+            'OBJECT_IMAGES_TRANSCODER_COVER_THUMB' => 'bx_persons_cover_thumb',
+            'OBJECT_VIEWS' => 'bx_persons',
+            'OBJECT_FORM_ENTRY' => 'bx_person',
+            'OBJECT_FORM_ENTRY_DISPLAY_VIEW' => 'bx_person_view',
+            'OBJECT_FORM_ENTRY_DISPLAY_ADD' => 'bx_person_add',
+            'OBJECT_FORM_ENTRY_DISPLAY_EDIT' => 'bx_person_edit',
+            'OBJECT_FORM_ENTRY_DISPLAY_EDIT_COVER' => 'bx_person_edit_cover',
+            'OBJECT_FORM_ENTRY_DISPLAY_DELETE' => 'bx_person_delete',
+            'OBJECT_MENU_ACTIONS_VIEW_ENTRY' => 'bx_persons_view_actions', // actions menu on view entry page
+            'OBJECT_MENU_ACTIONS_VIEW_ENTRY_MORE' => 'bx_persons_view_actions_more', // actions menu on view entry page for "more" popup
+            'OBJECT_MENU_SUBMENU_VIEW_ENTRY' => 'bx_persons_view_submenu',  // view entry submenu
+
+            // menu items which visibility depends on custom visibility checking
+            'MENU_ITEM_TO_METHOD' => array (
+                'bx_persons_view_actions' => $aMenuItems2Methods,
+                'bx_persons_view_actions_more' => $aMenuItems2Methods,
+            ),
+
+            // informer messages
+            'INFORMERS' => array (
+                'status' => array (
+                    'name' => 'bx-persons-status-not-active',
+                    'map' => array (
+                        BX_PROFILE_STATUS_PENDING => '_bx_persons_txt_account_pending',
+                        BX_PROFILE_STATUS_SUSPENDED => '_bx_persons_txt_account_suspended',
+                    ),
+                ),
+            ),
+
+            // some language keys
+            'T' => array (
+                'menu_item_title_befriend_sent' => '_bx_persons_menu_item_title_befriend_sent', 
+                'menu_item_title_unfriend_cancel_request' => '_bx_persons_menu_item_title_unfriend_cancel_request',
+                'menu_item_title_befriend_confirm' => '_bx_persons_menu_item_title_befriend_confirm',
+                'menu_item_title_unfriend_reject_request' => '_bx_persons_menu_item_title_unfriend_reject_request',
+                'menu_item_title_befriend' => '_bx_persons_menu_item_title_befriend',
+                'menu_item_title_unfriend' => '_bx_persons_menu_item_title_unfriend',
+            ),
+
+        );
     }
 
 }

+ 2 - 23
modules/boonex/persons/classes/BxPersonsDb.php

@@ -9,38 +9,17 @@
  * @{
  */
 
-bx_import('BxDolModuleDb');
+bx_import('BxBaseModProfileDb');
 
 /*
  * Persons module database queries
  */
-class BxPersonsDb extends BxDolModuleDb 
+class BxPersonsDb extends BxBaseModProfileDb 
 {
-    /*
-     * Constructor.
-     */
     public function __construct(&$oConfig) 
     {
         parent::__construct($oConfig);
     }
-
-    public function getContentInfoById ($iContentId) 
-    {
-        $sQuery = $this->prepare ("SELECT `c`.*, `p`.`account_id`, `p`.`id` AS `profile_id`, `p`.`status` AS `profile_status` FROM `" . $this->_sPrefix . "data` AS `c` INNER JOIN `sys_profiles` AS `p` ON (`p`.`content_id` = `c`.`id` AND `p`.`type` = 'bx_persons') WHERE `c`.`id` = ?", $iContentId);
-        return $this->getRow($sQuery);
-    }
-
-    public function updateContentPictureById($iContentId, $iProfileId, $iPictureId, $sFieldPicture) 
-    {
-        $sQuery = $this->prepare ("UPDATE `" . $this->_sPrefix . "data` SET `" . $sFieldPicture . "` = ? WHERE `id` = ? AND `author` = ?", $iPictureId, $iContentId, $iProfileId);
-        return $this->res($sQuery);
-    }
-
-    public function searchByTerm($sTerm, $iLimit) 
-    {
-        $sQuery = $this->prepare("SELECT `c`.`id` AS `content_id`, `p`.`account_id`, `p`.`id` AS `profile_id`, `p`.`status` AS `profile_status` FROM `" . $this->_sPrefix . "data` AS `c` INNER JOIN `sys_profiles` AS `p` ON (`p`.`content_id` = `c`.`id` AND `p`.`type` = 'bx_persons') WHERE `p`.`status` = ? AND `c`.`fullname` LIKE ? ORDER BY `added` DESC LIMIT ?", BX_PROFILE_STATUS_ACTIVE, '%' . $sTerm . '%', (int)$iLimit);
-        return $this->getAll($sQuery);
-    }
 }
 
 /** @} */ 

+ 29 - 0
modules/boonex/persons/classes/BxPersonsFormEntry.php

@@ -0,0 +1,29 @@
+<?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    Persons Persons
+ * @ingroup     DolphinModules
+ *
+ * @{
+ */
+
+bx_import('BxBaseModProfileFormEntry');
+bx_import('BxDolProfile');
+bx_import('BxDolStorage');
+bx_import('BxDolImageTranscoder');
+
+/**
+ * Create/Edit Person Form.
+ */
+class BxPersonsFormEntry extends BxBaseModProfileFormEntry 
+{
+    public function __construct($aInfo, $oTemplate = false)
+    {
+        $this->MODULE = 'bx_persons';
+        parent::__construct($aInfo, $oTemplate);
+    }
+}
+
+/** @} */

+ 25 - 0
modules/boonex/persons/classes/BxPersonsFormsEntryHelper.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    Persons Persons
+ * @ingroup     DolphinModules
+ *
+ * @{
+ */
+
+bx_import('BxBaseModProfileFormsEntryHelper');
+
+/**
+ * Person profile forms functions
+ */
+class BxPersonsFormsEntryHelper extends BxBaseModProfileFormsEntryHelper 
+{
+    public function __construct($oModule) 
+    {
+        parent::__construct($oModule);
+    }
+}
+
+/** @} */

+ 27 - 0
modules/boonex/persons/classes/BxPersonsMenuView.php

@@ -0,0 +1,27 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * CC-BY License - http://creativecommons.org/licenses/by/3.0/
+ *
+ * @defgroup    Persons Persons
+ * @ingroup     DolphinModules
+ *
+ * @{
+ */
+
+bx_import('BxBaseModProfileMenuView');
+
+/**
+ * 'View person' menu.
+ */
+class BxPersonsMenuView extends BxBaseModProfileMenuView 
+{
+
+    public function __construct($aObject, $oTemplate = false) 
+    {
+        $this->MODULE = 'bx_persons';
+        parent::__construct($aObject, $oTemplate);
+    }
+}
+
+/** @} */

+ 0 - 119
modules/boonex/persons/classes/BxPersonsMenuViewPerson.php

@@ -1,119 +0,0 @@
-<?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    Persons Persons
- * @ingroup     DolphinModules
- *
- * @{
- */
-
-bx_import('BxTemplMenu');
-bx_import('BxDolProfile');
-bx_import('BxDolModule');
-
-/**
- * 'View person' menu.
- */
-class BxPersonsMenuViewPerson extends BxTemplMenu {
-
-    protected $_oProfile;
-    protected $_aContentInfo;
-    protected $_aProfileInfo;
-    protected $_oModule;
-
-    public function __construct($aObject, $oTemplate = false) {
-        parent::__construct($aObject, $oTemplate);
-
-        $iProfileId = bx_process_input(bx_get('profile_id'), BX_DATA_INT);
-        $iContentId = bx_process_input(bx_get('id'), BX_DATA_INT);
-        if ($iProfileId)
-            $this->_oProfile = BxDolProfile::getInstance($iProfileId);
-        if (!$this->_oProfile && $iContentId)
-            $this->_oProfile = BxDolProfile::getInstanceByContentAndType($iContentId, 'bx_persons');
-
-        if ($this->_oProfile) {
-            $this->_aProfileInfo = $this->_oProfile->getInfo();
-
-            $this->_oModule = BxDolModule::getInstance('bx_persons');
-            $this->_aContentInfo = $this->_oModule->_oDb->getContentInfoById($this->_aProfileInfo['content_id']);
-
-            $this->addMarkers($this->_aProfileInfo);
-            $this->addMarkers(array('profile_id' => $this->_oProfile->id()));
-
-            if (isLogged()) {
-                bx_import('BxDolConnection');
-                $oConn = BxDolConnection::getObjectInstance('sys_profiles_friends');
-                if ($oConn->isConnectedNotMutual(bx_get_logged_profile_id(), $this->_oProfile->id()))
-                    $this->addMarkers(array(
-                        'title_add_friend' => _t('_bx_persons_menu_item_title_befriend_sent'), 
-                        'title_remove_friend' => _t('_bx_persons_menu_item_title_unfriend_cancel_request'),
-                    ));
-                elseif ($oConn->isConnectedNotMutual($this->_oProfile->id(), bx_get_logged_profile_id()))
-                    $this->addMarkers(array(
-                        'title_add_friend' => _t('_bx_persons_menu_item_title_befriend_confirm'),
-                        'title_remove_friend' => _t('_bx_persons_menu_item_title_unfriend_reject_request'),
-                    ));
-                else
-                    $this->addMarkers(array(
-                        'title_add_friend' => _t('_bx_persons_menu_item_title_befriend'),
-                        'title_remove_friend' => _t('_bx_persons_menu_item_title_unfriend'),
-                    ));
-            }
-        }
-    }
-
-    /**
-     * Check if menu items is visible.
-     * @param $a menu item array
-     * @return boolean
-     */ 
-    protected function _isVisible ($a) {
-
-        // default visible settings
-        bx_import('BxDolAcl');
-        if (!BxDolAcl::getInstance()->isMemberLevelInSet($a['visible_for_levels']))
-            return false;
-
-        // don't show current item, also this will solve problem when only one view note item is visible
-//        if ('bx_persons_view_actions' == $this->_sObject && $this->_isSelected($a))
-//            return false;
-
-        $sFuncCheckAccess = false;
-        switch ($a['name']) {
-            case 'view-persons-profile':
-                $sFuncCheckAccess = 'isAllowedView';
-                break;
-            case 'edit-persons-profile':
-                $sFuncCheckAccess = 'isAllowedEdit';
-                break;
-            case 'delete-persons-profile':
-                $sFuncCheckAccess = 'isAllowedDelete';
-                break;
-            case 'profile-friend-add':
-                $sFuncCheckAccess = 'isAllowedFriendAdd';
-                break;
-            case 'profile-friend-remove':
-                $sFuncCheckAccess = 'isAllowedFriendRemove';
-                break;
-            case 'profile-subscribe-add':
-                $sFuncCheckAccess = 'isAllowedSubscribeAdd';
-                break;
-            case 'profile-subscribe-remove':
-                $sFuncCheckAccess = 'isAllowedSubscribeRemove';
-                break;
-            case 'profile-actions-more':
-                $sFuncCheckAccess = 'isAllowedViewMoreMenu';
-                break;            
-        }
-
-        if (!$sFuncCheckAccess)
-            return true;
-
-        return $sFuncCheckAccess && $this->_oModule && CHECK_ACTION_RESULT_ALLOWED === $this->_oModule->$sFuncCheckAccess($this->_aContentInfo) ? true : false;
-    }
-
-}
-
-/** @} */

+ 6 - 404
modules/boonex/persons/classes/BxPersonsModule.php

@@ -9,414 +9,16 @@
  * @{
  */
 
-bx_import ('BxDolModule');
-bx_import ('BxDolAcl');
+bx_import ('BxBaseModProfileModule');
 
 /**
- * Persons module
- *
- * Basic person profiles.
+ * Person profiles module.
  */
-class BxPersonsModule extends BxDolModule implements iBxDolProfileService {
-
-    protected $_iProfileId;
-    protected $_iAccountId;
-
-    function __construct(&$aModule) {
+class BxPersonsModule extends BxBaseModProfileModule
+{
+    function __construct(&$aModule) 
+    {
         parent::__construct($aModule);
-        $this->_iProfileId = bx_get_logged_profile_id();
-        $this->_iAccountId = getLoggedId();
-    }
-
-    // ====== SERVICE METHODS
-
-    public function serviceProfilesSearch ($sTerm, $iLimit) {
-        $aRet = array();
-        $a = $this->_oDb->searchByTerm($sTerm, $iLimit);
-        foreach ($a as $r)
-            $aRet[] = array ('label' => $this->serviceProfileName($r['content_id']), 'value' => $r['profile_id']);
-        return $aRet;
-    }
-
-    public function serviceProfileUnit ($iContentId) {
-        return $this->_serviceTemplateFunc('unit', $iContentId);
-    }
-
-    public function serviceProfileAvatar ($iContentId) {
-        return $this->_serviceTemplateFunc('urlAvatar', $iContentId);
-    }
-
-    public function serviceProfileEditUrl ($iContentId) {
-        bx_import('BxDolPermalinks');
-        return BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=edit-persons-profile&id=' . $iContentId);
-    }
-
-    public function serviceProfileThumb ($iContentId) {
-        return $this->_serviceTemplateFunc('thumb', $iContentId);
-    }
-
-    public function serviceProfileIcon ($iContentId) {
-        return $this->_serviceTemplateFunc('icon', $iContentId);
-    }
-
-    protected function _serviceTemplateFunc ($sFunc, $iContentId) {
-        if (!$iContentId)
-            return false;
-        $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
-        if (!$aContentInfo)
-            return false;        
-        return $this->_oTemplate->$sFunc($aContentInfo);
-    }
-
-    public function serviceProfileName ($iContentId) {
-        if (!$iContentId)
-            return false;
-        $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
-        if (!$aContentInfo)
-            return false;        
-        return $aContentInfo[BxPersonsConfig::$FIELD_NAME];
-    }
-
-    public function serviceProfileUrl ($iContentId) {
-        if (!$iContentId)
-            return false;
-        $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
-        if (!$aContentInfo)
-            return false;
-        bx_import('BxDolPermalinks');
-        return BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=view-persons-profile&id=' . $aContentInfo['id']);
-    }
-
-    public function serviceBrowseRecentPersons () {
-        return $this->_serviceBrowse ('recent');
-    }
-
-    public function serviceBrowseConnections ($iProfileId, $sObjectConnections = 'sys_profiles_friends', $sConnectionsType = 'content', $iMutual = false, $iDesignBox = BX_DB_PADDING_DEF, $iProfileId2 = 0) {
-        return $this->_serviceBrowse (
-            'connections', 
-            array(
-                'object' => $sObjectConnections,
-                'type' => $sConnectionsType,
-                'mutual' => $iMutual,
-                'profile' => (int)$iProfileId,  
-                'profile2' => (int)$iProfileId2),
-            $iDesignBox
-        );
-    }
-
-    protected function _serviceBrowse ($sMode, $aParams = false, $iDesignBox = BX_DB_PADDING_DEF) {
-        bx_import('SearchResult', $this->_aModule);
-        $sClass = $this->_aModule['class_prefix'] . 'SearchResult';
-        $o = new $sClass($sMode, $aParams);
-
-        $o->setDesignBoxTemplateId($iDesignBox);
-
-        if ($o->isError)
-            return false;
-
-        if ($s = $o->processing())
-            return $s;
-        else
-            return false;
-    }
-
-    public function serviceCreateProfile () {
-        bx_import('ProfileForms', $this->_aModule);
-        $oProfileForms = new BxPersonsProfileForms($this);
-        return $oProfileForms->addDataForm();
-    }
-
-    public function serviceEditProfile ($iContentId = 0) {
-        if (!$iContentId)
-            $iContentId = bx_process_input(bx_get('id'), BX_DATA_INT);
-        if (!$iContentId)
-            return false;
-        bx_import('ProfileForms', $this->_aModule);
-        $oProfileForms = new BxPersonsProfileForms($this);
-        return $oProfileForms->editDataForm((int)$iContentId);
-    }
-
-    public function serviceEditCover ($iContentId = 0) {
-        if (!$iContentId)
-            $iContentId = bx_process_input(bx_get('id'), BX_DATA_INT);
-        if (!$iContentId)
-            return false;
-        bx_import('ProfileForms', $this->_aModule);
-        $oProfileForms = new BxPersonsProfileForms($this);
-        return $oProfileForms->editDataForm((int)$iContentId, 'bx_person_edit_cover');
-    }
-
-    public function serviceDeleteProfile ($iContentId = 0) {
-        if (!$iContentId)
-            $iContentId = bx_process_input(bx_get('id'), BX_DATA_INT);
-        if (!$iContentId)
-            return false;
-        bx_import('ProfileForms', $this->_aModule);
-        $oProfileForms = new BxPersonsProfileForms($this);
-        return $oProfileForms->deleteDataForm((int)$iContentId);
-    }
-
-    public function serviceProfileInfo ($iContentId = 0) {
-        if (!$iContentId)
-            $iContentId = bx_process_input(bx_get('id'), BX_DATA_INT);
-        if (!$iContentId)
-            return false;
-
-        bx_import('ProfileForms', $this->_aModule);
-        $oProfileForms = new BxPersonsProfileForms($this);
-        return $oProfileForms->viewDataForm((int)$iContentId);
-    }
-
-    public function serviceProfileCover ($iContentId = 0) {
-       if (!$iContentId)
-            $iContentId = bx_process_input(bx_get('id'), BX_DATA_INT);
-        if (!$iContentId)
-            return false;
-
-        $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
-        if (!$aContentInfo)
-            return false;
-
-        return $this->_oTemplate->cover($aContentInfo);
-    }
-
-    public function serviceProfileActions ($iContentId = 0) {
-       if (!$iContentId)
-            $iContentId = bx_process_input(bx_get('id'), BX_DATA_INT);
-        if (!$iContentId)
-            return false;
-
-        bx_import('BxTemplMenu');
-        $oMenu = BxTemplMenu::getObjectInstance('bx_persons_view_actions');
-        return $oMenu ? $oMenu->getCode() : false;
-    }
-
-    public function serviceProfileFriends ($iContentId = 0) {
-        if (!$iContentId)
-            $iContentId = bx_process_input(bx_get('id'), BX_DATA_INT);
-        if (!$iContentId)
-            return false;
-
-        $aContentInfo = $this->_oDb->getContentInfoById($iContentId);
-        if (!$aContentInfo)
-            return false;
-        
-        return 'TODO: friends here';
-    }
-
-    // ====== ACTION METHODS
-
-    function actionBrowse ($sMode = '') {
-
-        $sMode = bx_process_input($sMode);
-
-/*
-        if ('user' == $sMode || 'my' == $sMode) {
-            $aProfile = getProfileInfo ($this->_iProfileId);
-            if (0 == strcasecmp($sValue, $aProfile['NickName']) || 'my' == $sMode) {
-                $this->_browseMy ($aProfile);
-                return;
-            }
-        }
-
-        if ('tag' == $sMode || 'category' == $sMode)
-            $sValue = uri2title($sValue);
-*/
-
-        if (CHECK_ACTION_RESULT_ALLOWED !== $this->isAllowedBrowse()) {
-            $this->_oTemplate->displayAccessDenied ();
-            return;
-        }
-
-        bx_import ('SearchResult', $this->_aModule);
-        $sClass = $this->_aModule['class_prefix'] . 'SearchResult';
-        $o = new $sClass($sMode);
-
-        if ($o->isError) {
-            $this->_oTemplate->displayPageNotFound ();
-            return;
-        }
-
-        if (bx_get('rss')) {
-            echo $o->rss();
-            exit;
-        }
-
-        if (!($s = $o->processing())) {
-            $this->_oTemplate->displayNoData ();
-            return;
-        }
-
-        // TODO: remale to use "pages"
-
-        $this->_oTemplate->addCss ('main.css'); 
-
-        $oTemplate = BxDolTemplate::getInstance();
-        $oTemplate->setPageHeader ($o->aCurrent['title']);
-        $oTemplate->setPageNameIndex (BX_PAGE_DEFAULT);
-        $oTemplate->setPageContent ('page_main_code', $s);
-        $oTemplate->getPageCode();
-    }
-
-    // ====== PERMISSION METHODS
-
-    function _checkModeratorAccess ($isPerformAction = false) {
-        // check moderator ACL
-        $aCheck = checkActionModule($this->_iProfileId, 'edit any person profile', $this->getName(), $isPerformAction); 
-        return $aCheck[CHECK_ACTION_RESULT] === CHECK_ACTION_RESULT_ALLOWED;
-    }
-
-    /**
-     * @return CHECK_ACTION_RESULT_ALLOWED if access is granted or error message if access is forbidden. So make sure to make "true === " checking.
-     */
-    function isAllowedView ($aDataEntry, $isPerformAction = false) {
-
-        // moderator and owner always have access
-        if ($aDataEntry[BxPersonsConfig::$FIELD_AUTHOR] == $this->_iProfileId || $this->_checkModeratorAccess($isPerformAction))
-            return CHECK_ACTION_RESULT_ALLOWED;
-
-        // check ACL
-        $aCheck = checkActionModule($this->_iProfileId, 'view person profile', $this->getName(), $isPerformAction);
-        if ($aCheck[CHECK_ACTION_RESULT] !== CHECK_ACTION_RESULT_ALLOWED)
-            return $aCheck[CHECK_ACTION_MESSAGE];
-
-        // TODO: check privacy
-
-        return CHECK_ACTION_RESULT_ALLOWED;
-    }
-
-    /**
-     * @return CHECK_ACTION_RESULT_ALLOWED if access is granted or error message if access is forbidden. So make sure to make "true === " checking.
-     */
-    function isAllowedBrowse () {
-        return CHECK_ACTION_RESULT_ALLOWED;
-    }
-
-    /**
-     * @return CHECK_ACTION_RESULT_ALLOWED if access is granted or error message if access is forbidden. 
-     */
-    function isAllowedAdd ($isPerformAction = false) {
-        // check ACL
-        $aCheck = checkActionModule($this->_iProfileId, 'create person profile', $this->getName(), $isPerformAction);
-        if ($aCheck[CHECK_ACTION_RESULT] !== CHECK_ACTION_RESULT_ALLOWED)
-            return $aCheck[CHECK_ACTION_MESSAGE];
-        return CHECK_ACTION_RESULT_ALLOWED;
-    }
-
-    /**
-     * @return CHECK_ACTION_RESULT_ALLOWED if access is granted or error message if access is forbidden. 
-     */
-    function isAllowedEdit ($aDataEntry, $isPerformAction = false) {
-        // moderator always has access
-        if ($this->_checkModeratorAccess($isPerformAction))
-            return CHECK_ACTION_RESULT_ALLOWED;
-
-        // owner (checked by account! not as profile as ususal) always have access
-        bx_import('BxDolProfile');
-        $oProfileAurhor = BxDolProfile::getInstance($aDataEntry[BxPersonsConfig::$FIELD_AUTHOR]);
-        if ($oProfileAurhor->getAccountId() == $this->_iAccountId)
-            return CHECK_ACTION_RESULT_ALLOWED;
-
-        return _t('_sys_txt_access_denied');
-    }
-
-    /**
-     * Check if user can change cover image
-     */
-    function isAllowedChangeCover ($aDataEntry, $isPerformAction = false) {
-        // moderator always has access
-        if ($this->_checkModeratorAccess($isPerformAction))
-            return CHECK_ACTION_RESULT_ALLOWED;
-
-        // owner (checked by account! not as profile as ususal) always have access
-        bx_import('BxDolProfile');
-        $oProfileAurhor = BxDolProfile::getInstance($aDataEntry[BxPersonsConfig::$FIELD_AUTHOR]);
-        if ($oProfileAurhor->getAccountId() == $this->_iAccountId)
-            return CHECK_ACTION_RESULT_ALLOWED;
-
-        return _t('_sys_txt_access_denied');
-    }
-
-    /**
-     * @return CHECK_ACTION_RESULT_ALLOWED if access is granted or error message if access is forbidden. 
-     */
-    function isAllowedDelete (&$aDataEntry, $isPerformAction = false) {
-        // moderator always has access
-        if ($this->_checkModeratorAccess($isPerformAction))
-            return CHECK_ACTION_RESULT_ALLOWED;
-
-        // check ACL and owner (checked by account! not as profile as ususal)
-        bx_import('BxDolProfile');
-        $oProfileAurhor = BxDolProfile::getInstance($aDataEntry[BxPersonsConfig::$FIELD_AUTHOR]);
-
-        $aCheck = checkActionModule($this->_iProfileId, 'delete person profile', $this->getName(), $isPerformAction);
-        if ($oProfileAurhor->getAccountId() == $this->_iAccountId && $aCheck[CHECK_ACTION_RESULT] === CHECK_ACTION_RESULT_ALLOWED)
-            return CHECK_ACTION_RESULT_ALLOWED;
-
-        return _t('_sys_txt_access_denied');
-    }
-
-    /**
-     * @return CHECK_ACTION_RESULT_ALLOWED if access is granted or error message if access is forbidden. 
-     */
-    function isAllowedViewMoreMenu (&$aDataEntry, $isPerformAction = false) {
-        bx_import('BxTemplMenu');
-        $oMenu = BxTemplMenu::getObjectInstance('bx_persons_view_actions_more');
-        if (!$oMenu || !$oMenu->getCode())
-            return _t('_sys_txt_access_denied');
-        return CHECK_ACTION_RESULT_ALLOWED;
-    }
-
-    /**
-     * @return CHECK_ACTION_RESULT_ALLOWED if access is granted or error message if access is forbidden. 
-     */
-    function isAllowedFriendAdd (&$aDataEntry, $isPerformAction = false) {
-        return $this->_isAllowedConnect ($aDataEntry, $isPerformAction, 'sys_profiles_friends', true, false);
-    }
-
-    /**
-     * @return CHECK_ACTION_RESULT_ALLOWED if access is granted or error message if access is forbidden. 
-     */
-    function isAllowedFriendRemove (&$aDataEntry, $isPerformAction = false) {
-        if (CHECK_ACTION_RESULT_ALLOWED === $this->_isAllowedConnect ($aDataEntry, $isPerformAction, 'sys_profiles_friends', false, true, true))
-            return CHECK_ACTION_RESULT_ALLOWED;
-        return $this->_isAllowedConnect ($aDataEntry, $isPerformAction, 'sys_profiles_friends', false, true, false);
-    }
-
-    /**
-     * @return CHECK_ACTION_RESULT_ALLOWED if access is granted or error message if access is forbidden. 
-     */
-    function isAllowedSubscribeAdd (&$aDataEntry, $isPerformAction = false) {
-        return $this->_isAllowedConnect ($aDataEntry, $isPerformAction, 'sys_profiles_subscriptions', false, false);
-    }
-
-    /**
-     * @return CHECK_ACTION_RESULT_ALLOWED if access is granted or error message if access is forbidden. 
-     */
-    function isAllowedSubscribeRemove (&$aDataEntry, $isPerformAction = false) {
-        return $this->_isAllowedConnect ($aDataEntry, $isPerformAction, 'sys_profiles_subscriptions', false, true);
-    }
-
-    function _isAllowedConnect (&$aDataEntry, $isPerformAction, $sObjConnection, $isMutual, $isInvertResult, $isSwap = false) {
-        if (!$this->_iProfileId)
-            return _t('_sys_txt_access_denied');
-
-        $oProfileAuthor = BxDolProfile::getInstance($aDataEntry[BxPersonsConfig::$FIELD_AUTHOR]);
-        $oProfile = $oProfileAuthor ? BxDolProfile::getInstanceByContentTypeAccount($aDataEntry[BxPersonsConfig::$FIELD_ID], 'bx_persons', $oProfileAuthor->getAccountId()) : false;
-        if (!$oProfile || $oProfile->id() == $this->_iProfileId)
-            return _t('_sys_txt_access_denied');
-
-        bx_import('BxDolConnection');
-        $oConn = BxDolConnection::getObjectInstance($sObjConnection);
-        if ($isSwap)
-            $isConnected = $oConn->isConnected($oProfile->id(), $this->_iProfileId, $isMutual);
-        else
-            $isConnected = $oConn->isConnected($this->_iProfileId, $oProfile->id(), $isMutual);
-
-        if ($isInvertResult)
-            $isConnected = !$isConnected;
-
-        return $isConnected ? _t('_sys_txt_access_denied') : CHECK_ACTION_RESULT_ALLOWED;
     }
 }
 

+ 27 - 0
modules/boonex/persons/classes/BxPersonsPageEntry.php

@@ -0,0 +1,27 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
+ * CC-BY License - http://creativecommons.org/licenses/by/3.0/
+ *
+ * @defgroup    Persons Persons
+ * @ingroup     DolphinModules
+ *
+ * @{
+ */
+
+bx_import('BxBaseModProfilePageEntry');
+
+/**
+ * Profile create/edit/delete pages.
+ */
+class BxPersonsPageEntry extends BxBaseModProfilePageEntry 
+{
+    public function __construct($aObject, $oTemplate = false) 
+    {
+        $this->MODULE = 'bx_persons';
+        parent::__construct($aObject, $oTemplate);
+    }
+
+}
+
+/** @} */

+ 0 - 213
modules/boonex/persons/classes/BxPersonsProfileForms.php

@@ -1,213 +0,0 @@
-<?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    Persons Persons
- * @ingroup     DolphinModules
- *
- * @{
- */
-
-bx_import('BxDolProfileForms');
-bx_import('BxDolProfile');
-bx_import('BxDolForm');
-
-/**
- * Person profile forms functions
- */
-class BxPersonsProfileForms extends BxDolProfileForms {
-
-    protected $_oModule;
-
-    public function __construct($oModule) {
-        parent::__construct();
-        $this->_oModule = $oModule;
-    }
-
-    public function addDataForm () {
-
-        // check access
-        if (CHECK_ACTION_RESULT_ALLOWED !== ($sMsg = $this->_oModule->isAllowedAdd()))
-            return MsgBox($sMsg);
-
-        // check and display form
-        $oForm = BxDolForm::getObjectInstance('bx_person', 'bx_person_add'); 
-        if (!$oForm)
-            return MsgBox(_t('_sys_txt_error_occured'));
-
-        $oForm->initChecker(); 
-
-        if (!$oForm->isSubmittedAndValid())
-            return $oForm->getCode();
-
-        // insert data into database
-        $aValsToAdd = array ();        
-        $iContentId = $oForm->insert ($aValsToAdd);
-        if (!$iContentId) {
-            if (!$oForm->isValid())
-                return $oForm->getCode();
-            else
-                return MsgBox(_t('_sys_txt_error_entry_creation'));
-        }
-
-        // add account and content association
-        $iProfileId = BxDolProfile::add(BX_PROFILE_ACTION_MANUAL, getLoggedId(), $iContentId, BX_PROFILE_STATUS_PENDING, $this->_oModule->getName());
-        $oProfile = BxDolProfile::getInstance($iProfileId);
-
-        // approve profile if auto-approval is enabled and profile status is 'pending'
-        $sStatus = $oProfile->getStatus();
-        $isAutoApprove = getParam('bx_persons_autoapproval') ? true : false;
-        if ($sStatus == BX_PROFILE_STATUS_PENDING && $isAutoApprove)
-            $oProfile->approve(BX_PROFILE_ACTION_AUTO);
-
-        // set created profile some default membership
-        bx_import('BxDolAcl');
-        $iAclLevel = getParam('bx_persons_default_acl_level');
-        BxDolAcl::getInstance()->setMembership($iProfileId, $iAclLevel, 0, true); 
-
-        // perform action 
-        $this->_oModule->isAllowedAdd(true);
-
-        // alert
-        bx_alert($this->_oModule->getName(), 'added', $iContentId);
-
-        // switch context to the created profile
-        bx_import('BxDolAccount');
-        $oAccount = BxDolAccount::getInstance();
-        $oAccount->updateProfileContext($iProfileId);
-
-        // redirect 
-        $this->_redirectAndExit('page.php?i=view-persons-profile&id=' . $iContentId);
-    }
-
-    public function editDataForm ($iContentId, $sDisplay = 'bx_person_edit') {
-
-        // get content data and profile info
-        list ($oProfile, $aProfileInfo, $aContentInfo) = $this->_getProfileAndContentData($iContentId);
-        if (!$aContentInfo)
-            return MsgBox(_t('_sys_txt_error_entry_is_not_defined')); 
-
-        // check access
-        if (CHECK_ACTION_RESULT_ALLOWED !== ($sMsg = $this->_oModule->isAllowedEdit($aContentInfo)))
-            return MsgBox($sMsg);
-        
-        // check and display form 
-        $oForm = BxDolForm::getObjectInstance('bx_person', $sDisplay); 
-        if (!$oForm)
-            return MsgBox(_t('_sys_txt_error_occured'));
-
-        $oForm->initChecker($aContentInfo); 
-
-        if (!$oForm->isSubmittedAndValid())
-            return $oForm->getCode();
-
-        // update data in the DB
-        $aTrackTextFieldsChanges = null;
-        $isAutoApprove = getParam('bx_persons_autoapproval') ? true : false;
-        if (!$isAutoApprove && BX_PROFILE_STATUS_ACTIVE == $aProfileInfo['status'])
-            $aTrackTextFieldsChanges = array ();
-
-        if (!$oForm->update ($aContentInfo['id'], array(), $aTrackTextFieldsChanges)) {
-            if (!$oForm->isValid())
-                return $oForm->getCode();
-            else
-                return MsgBox(_t('_sys_txt_error_entry_update')); 
-        }
-
-        // change profile to 'pending' only if profile is 'active'
-        if (!$isAutoApprove && BX_PROFILE_STATUS_ACTIVE == $aProfileInfo['status'] && !empty($aTrackTextFieldsChanges['changed_fields']))
-            $oProfile->disapprove(BX_PROFILE_ACTION_AUTO);
-
-        // perform action
-        $this->_oModule->isAllowedEdit($aContentInfo, true);
-
-        // create an alert
-        bx_alert($this->_oModule->getName(), 'edited', $aContentInfo['id']); 
-
-        // redirect 
-        $this->_redirectAndExit('page.php?i=view-persons-profile&id=' . $aContentInfo['id']);
-    }
-
-    public function deleteDataForm ($iContentId) {
-
-        // get content data and profile info
-        list ($oProfile, $aProfileInfo, $aContentInfo) = $this->_getProfileAndContentData($iContentId);
-        if (!$aContentInfo)
-            return MsgBox(_t('_sys_txt_error_entry_is_not_defined')); 
-
-        // check access
-        if (CHECK_ACTION_RESULT_ALLOWED !== ($sMsg = $this->_oModule->isAllowedDelete($aContentInfo)))
-            return MsgBox($sMsg);
-        
-        // check and display form 
-        $oForm = BxDolForm::getObjectInstance('bx_person', 'bx_person_delete'); 
-        if (!$oForm)
-            return MsgBox(_t('_sys_txt_error_occured'));
-
-        $oForm->initChecker($aContentInfo); 
-
-        if (!$oForm->isSubmittedAndValid())
-            return $oForm->getCode();
-
-        // delete avatar & avatar
-        if (!$oForm->delete ($aContentInfo['id'], $aContentInfo))
-            return MsgBox(_t('_sys_txt_error_entry_delete')); 
-
-        // delete profile
-        if (!$oProfile->delete($aContentInfo['profile_id']))
-            return MsgBox(_t('_sys_txt_error_entry_delete')); 
-
-        // perform action
-        $this->_oModule->isAllowedDelete($aContentInfo, true);
-
-        // create an alert
-        bx_alert($this->_oModule->getName(), 'deleted', $aContentInfo['id']); 
-
-        // redirect
-        $this->_redirectAndExit('member.php', false); 
-    }
-
-    public function viewDataForm ($iContentId) {
-
-        // get content data and profile info
-        list ($oProfile, $aProfileInfo, $aContentInfo) = $this->_getProfileAndContentData($iContentId);
-        if (!$aContentInfo)
-            return MsgBox(_t('_sys_txt_error_entry_is_not_defined')); 
-
-        // check access
-        if (CHECK_ACTION_RESULT_ALLOWED !== ($sMsg = $this->_oModule->isAllowedView($aContentInfo)))
-            return MsgBox($sMsg);
-        
-        // get form 
-        $oForm = BxDolForm::getObjectInstance('bx_person', 'bx_person_view'); 
-        if (!$oForm)
-            return MsgBox(_t('_sys_txt_error_occured'));
-
-        // perform action
-        $this->_oModule->isAllowedView($aContentInfo);
-
-        // display profile
-        $oForm->initChecker($aContentInfo);
-        return $oForm->getCode();
-    }
-
-    protected function _getProfileAndContentData ($iContentId) {
-    
-        $aContentInfo = array();
-        $aProfileInfo = array();
-        $oProfile = false;
-        
-        $aContentInfo = $this->_oModule->_oDb->getContentInfoById($iContentId);
-        if (!$aContentInfo)
-            return array (false, false, false);
-
-        $oProfile = BxDolProfile::getInstance($aContentInfo['profile_id']);
-        $aProfileInfo = $oProfile->getInfo();
-
-        return array ($oProfile, $aProfileInfo, $aContentInfo);
-    }
-
-}
-
-/** @} */

+ 66 - 89
modules/boonex/persons/classes/BxPersonsSearchResult.php

@@ -9,77 +9,94 @@
  * @{
  */
 
-bx_import('BxTemplSearchResult');
-
-class BxPersonsSearchResult extends BxTemplSearchResult {
-
-    var $aCurrent = array(
-        'name' => 'bx_persons',
-        'title' => '_bx_persons_page_title_browse',
-        'table' => 'sys_profiles',
-        'ownFields' => array(),
-        'searchFields' => array('fullname'),
-        'restriction' => array(
-            'perofileStatus' => array('value' => 'active', 'field' => 'status', 'operator' => '='),
-            'perofileType' => array('value' => 'bx_persons', 'field' => 'type', 'operator' => '='),
-            'owner' => array('value' => '', 'field' => 'author', 'operator' => '=', 'table' => 'bx_persons_data'),
-        ),
-        'join' => array (
-            'profile' => array(
-                'type' => 'INNER',
-                'table' => 'bx_persons_data',
-                'mainField' => 'content_id',
-                'onField' => 'id',
-                'joinFields' => array('id', 'fullname', 'picture', 'added'),
+bx_import('BxBaseModProfileSearchResult');
+
+class BxPersonsSearchResult extends BxBaseModProfileSearchResult 
+{
+
+    function __construct($sMode = '', $aParams = false) 
+    {
+        parent::__construct($sMode, $aParams);
+
+        $this->aCurrent =  array(
+            'name' => 'bx_persons',
+            'title' => _t('_bx_persons_page_title_browse'),
+            'table' => 'sys_profiles',
+            'ownFields' => array(),
+            'searchFields' => array('fullname'),
+            'restriction' => array(
+                'perofileStatus' => array('value' => 'active', 'field' => 'status', 'operator' => '='),
+                'perofileType' => array('value' => 'bx_persons', 'field' => 'type', 'operator' => '='),
+                'owner' => array('value' => '', 'field' => 'author', 'operator' => '=', 'table' => 'bx_persons_data'),
             ),
-        ),
-        'paginate' => array('perPage' => 20, 'start' => 0),
-        'sorting' => 'none',
-        'rss' => array(
-            'title' => '',
-            'link' => '',
-            'image' => '',
-            'profile' => 0,
-            'fields' => array (
-                'Guid' => 'link',
-                'Link' => 'link',
-                'Title' => 'fullname',
-                'DateTimeUTS' => 'added',
-                'Desc' => 'fullname',
-                'Picture' => 'picture',
+            'join' => array (
+                'profile' => array(
+                    'type' => 'INNER',
+                    'table' => 'bx_persons_data',
+                    'mainField' => 'content_id',
+                    'onField' => 'id',
+                    'joinFields' => array('id', 'fullname', 'picture', 'added'),
+                ),
             ),
-        ),
-        'ident' => 'id'
-    );
-
-    function __construct($sMode = '', $mixedParams = false) {
+            'paginate' => array('perPage' => 20, 'start' => 0),
+            'sorting' => 'none',
+            'rss' => array(
+                'title' => '',
+                'link' => '',
+                'image' => '',
+                'profile' => 0,
+                'fields' => array (
+                    'Guid' => 'link',
+                    'Link' => 'link',
+                    'Title' => 'fullname',
+                    'DateTimeUTS' => 'added',
+                    'Desc' => 'fullname',
+                    'Picture' => 'picture',
+                ),
+            ),
+            'ident' => 'id'
+        );
 
-        $oModuleMain = $this->getMain();
+        $this->sFilterName = 'bx_persons_filter';
+        $this->oModule = $this->getMain();
 
         switch ($sMode) {
 
             case 'connections':
-                $aParams = $mixedParams;
                 bx_import('BxDolConnection');
                 $oConnection = isset($aParams['object']) ? BxDolConnection::getObjectInstance($aParams['object']) : false;
                 if ($oConnection && isset($aParams['profile']) && (int)$aParams['profile']) {
 
+                    $oProfile = BxDolProfile::getInstance($aParams['profile']);
+
                     $sMethod = 'getConnectedContentAsCondition';
                     if (isset($aParams['type']) && $aParams['type'] == 'initiators')
                         $sMethod = 'getConnectedInitiatorsAsCondition';
 
-                    if (isset($aParams['type']) && $aParams['type'] == 'common')
+                    if (isset($aParams['type']) && $aParams['type'] == 'common') {
+
                         $a = $oConnection->getCommonContentAsCondition('id', (int)$aParams['profile'], (int)$aParams['profile2'], isset($aParams['mutual']) ? $aParams['mutual'] : false);
-                    else
+                        $oProfile2 = BxDolProfile::getInstance($aParams['profile2']);
+                        if ($oProfile && $oProfile2)
+                            $this->aCurrent['title'] = _t('_bx_persons_page_title_browse_connections_mutual', $oProfile->getDisplayName(), $oProfile2->getDisplayName());
+
+                    } else {
+
                         $a = $oConnection->$sMethod('id', (int)$aParams['profile'], isset($aParams['mutual']) ? $aParams['mutual'] : false);
+                        if ($oProfile)
+                            $this->aCurrent['title'] = _t('_bx_persons_page_title_browse_connections', $oProfile->getDisplayName());
+
+                    }
+
                     $this->aCurrent['restriction'] = array_merge($this->aCurrent['restriction'], $a['restriction']);
                     $this->aCurrent['join'] = array_merge($this->aCurrent['join'], $a['join']);
+                    $this->aCurrent['rss']['link'] = 'modules/?r=persons/rss/' . $sMode . '/' . $aParams['object'] . '/' . $aParams['type'] . '/' . (int)$aParams['profile'] . '/' . (int)$aParams['profile2'] . '/' . (int)$aParams['mutual'];
 
                 }
                 break;
 
             case 'search':
-                $sValue = $mixedParams;
+                $sValue = isset($aParams['q']) ? $aParams['q'] : false;
                 if ($sValue)
                     $this->aCurrent['restriction']['keyword'] = array('value' => $sValue,'field' => '','operator' => 'against');
 
@@ -88,28 +105,9 @@ class BxPersonsSearchResult extends BxTemplSearchResult {
                 unset($this->aCurrent['rss']);
                 break;
 
-            case 'user':
-                $iProfileId = (int)$mixedParams;
-                $aContentInfo = $oModuleMain->_oDb->getContentInfoById($iContentId);
-                if (!$aContentInfo)
-                    $this->isError = true;
-                else
-                    $this->aCurrent['restriction']['owner']['value'] = $iProfileId;
-
-                $this->sBrowseUrl = "browse/user/$iProfileId";
-                $this->aCurrent['title'] = _t('_bx_persons_page_title_browse_by_author', $aContentInfo['fullname']); // TODO: owner name here
-                if (bx_get('rss')) {
-                    $aData = getProfileInfo($iProfileId);
-                    if ($aData['Avatar']) {
-                        if (!$aImage['no_image'])
-                            $this->aCurrent['rss']['image'] = $aImage['file'];
-                    }
-                }
-                break;
-            
             case 'recent':
             case '':
-                $this->sBrowseUrl = 'browse/recent';
+                $this->aCurrent['rss']['link'] = 'modules/?r=persons/rss/' . $sMode;
                 $this->aCurrent['title'] = _t('_bx_persons_page_title_browse_recent');
                 break;
 
@@ -117,17 +115,6 @@ class BxPersonsSearchResult extends BxTemplSearchResult {
                 $this->isError = true;
         }
 
-        // $this->aCurrent['paginate']['perPage'] = $oModuleMain->_oDb->getParam('bx_groups_perpage_browse'); // TODO:
-
-        if (isset($this->aCurrent['rss']))
-            $this->aCurrent['rss']['link'] = BX_DOL_URL_ROOT . $oModuleMain->_oConfig->getBaseUri() . $this->sBrowseUrl;
-
-        if (bx_get('rss')) {
-            $this->aCurrent['paginate']['perPage'] = 10;//$oModuleMain->_oDb->getParam('bx_groups_max_rss_num');
-        }
-
-        $this->sFilterName = 'bx_persons_filter';
-
         parent::__construct();
     }
 
@@ -146,23 +133,13 @@ class BxPersonsSearchResult extends BxTemplSearchResult {
     function displayResultBlock () {        
         $s = parent::displayResultBlock ();
         if ($s) {
-            $oModuleMain = $this->getMain();
-            BxDolTemplate::getInstance()->addDynamicLocation($oModuleMain->_oConfig->getHomePath(), $oModuleMain->_oConfig->getHomeUrl());
+            BxDolTemplate::getInstance()->addDynamicLocation($this->oModule->_oConfig->getHomePath(), $this->oModule->_oConfig->getHomeUrl());
             bx_import('BxTemplFunctions');
             return BxTemplFunctions::getInstance()->centerContent ($s, '.bx-persons-unit');
         }
         return '';
     }
 
-    function getMain() {
-        return BxDolModule::getInstance($this->aCurrent['name']);
-    }
-
-    function getRssUnitLink (&$a) {
-        bx_import('BxDolPermalinks');
-        return BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=view-persons-profile&id=' . $a['id']);
-    }
-
     function _getPseud () {
         return array(
             'id' => 'id',

+ 7 - 146
modules/boonex/persons/classes/BxPersonsTemplate.php

@@ -9,156 +9,17 @@
  * @{
  */
 
-bx_import('BxDolModuleTemplate');
+bx_import('BxBaseModProfileTemplate');
 
 /*
  * Persons module representation.
  */
-class BxPersonsTemplate extends BxDolModuleTemplate {
-
-    /**
-     * Constructor
-     */
-    function __construct(&$oConfig, &$oDb) {
-        parent::__construct($oConfig, $oDb);        
-        $this->addCss ('main.css');
-    }
-
-    /**
-     * Get profile unit
-     */
-    function unit ($aData, $isCheckPrivateContent = true, $sTemplateName = 'unit.html') {
-
-        // TODO: add privacy checking here
-    
-        // get person's url
-        bx_import('BxDolPermalinks');
-        $sUrl = BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=view-persons-profile&id=' . $aData['id']);
-
-        // generate html
-        $aVars = array (
-            'id' => $aData['id'],
-            'thumb_url' => $this->thumb ($aData),
-            'content_url' => $sUrl,
-            'title' => $aData[BxPersonsConfig::$FIELD_NAME],
-        );
-
-        return $this->parseHtmlByName($sTemplateName, $aVars);
-
-    }
-
-    /**
-     * Get profile cover
-     */
-    function cover ($aData, $sTemplateName = 'cover.html') {        
-
-        bx_import('BxDolPermalinks');
-
-        $oModuleMain = BxDolModule::getInstance('bx_persons');
-        $sUrl = BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=view-persons-profile&id=' . $aData['id']);
-
-        $sUrlPicture = $this->urlPicture ($aData);
-        $sUrlAvatar = $this->urlAvatar ($aData);
-        $sUrlPictureChange = BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=edit-persons-profile&id=' . $aData['id']);
-
-        $sUrlCover = $this->urlCover ($aData);
-        $sUrlCoverChange = BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=edit-persons-cover&id=' . $aData['id']);        
-
-        $sCoverPopup = '';
-        if ($aData[BxPersonsConfig::$FIELD_COVER]) {
-            bx_import('BxTemplFunctions');
-            $sCoverPopup = BxTemplFunctions::getInstance()->transBox('bx-persons-popup-cover', $this->parseHtmlByName('image_popup.html', array (
-                'image_url' => $sUrlCover,
-                'bx_if:owner' => array (
-                    'condition' => CHECK_ACTION_RESULT_ALLOWED === $oModuleMain->isAllowedChangeCover($aData),
-                    'content' => array (
-                        'change_image_url' => $sUrlCoverChange,
-                    ),
-                ),
-            )), true, true);
-        }
-
-        $sPicturePopup = '';
-        if ($aData[BxPersonsConfig::$FIELD_PICTURE]) {
-            bx_import('BxTemplFunctions');
-            $sPicturePopup = BxTemplFunctions::getInstance()->transBox('bx-persons-popup-picture', $this->parseHtmlByName('image_popup.html', array (
-                'image_url' => $sUrlPicture,
-                'bx_if:owner' => array (
-                    'condition' => CHECK_ACTION_RESULT_ALLOWED === $oModuleMain->isAllowedEdit($aData),
-                    'content' => array (
-                        'change_image_url' => $sUrlPictureChange,
-                    ),
-                ),
-            )), true, true);
-        }
-
-        // generate html        
-        $aVars = array (
-            'id' => $aData['id'],
-            'content_url' => $sUrl,
-            'title' => $aData[BxPersonsConfig::$FIELD_NAME],
-
-            'picture_avatar_url' => $sUrlAvatar,
-            'picture_url' => $sUrlPicture,
-            'picture_popup' => $sPicturePopup,
-            'picture_href' => !$aData[BxPersonsConfig::$FIELD_PICTURE] && CHECK_ACTION_RESULT_ALLOWED === $oModuleMain->isAllowedEdit($aData) ? $sUrlPictureChange : 'javascript:void(0);',
-
-            'cover_popup' => $sCoverPopup,
-            'cover_url' => $sUrlCover,
-            'cover_href' => !$aData[BxPersonsConfig::$FIELD_COVER] && CHECK_ACTION_RESULT_ALLOWED === $oModuleMain->isAllowedChangeCover($aData) ? $sUrlCoverChange : 'javascript:void(0);',
-        );
-
-        return $this->parseHtmlByName($sTemplateName, $aVars);
-
-    }
-
-    /**
-     * Get profile picture thumb url
-     */
-    function thumb ($aData, $bSubstituteNoImage = true) {
-        return $this->_image (BxPersonsConfig::$FIELD_PICTURE, BxPersonsConfig::$OBJECT_IMAGES_TRANSCODER_THUMB, 'no-picture-thumb.png', $aData, $bSubstituteNoImage);
-    }
-
-    /**
-     * Get profile picture icon url
-     */
-    function icon ($aData, $bSubstituteNoImage = true) {
-        return $this->_image (BxPersonsConfig::$FIELD_PICTURE, BxPersonsConfig::$OBJECT_IMAGES_TRANSCODER_ICON, 'no-picture-icon.png', $aData, $bSubstituteNoImage);
-    }
-
-    /**
-     * Get profile picture preview url
-     */
-    function urlAvatar ($aData, $bSubstituteNoImage = true) {
-        return $this->_image (BxPersonsConfig::$FIELD_PICTURE, BxPersonsConfig::$OBJECT_IMAGES_TRANSCODER_AVATAR, 'no-picture-preview.png', $aData, $bSubstituteNoImage);
-    }
-
-    /**
-     * Get profile picture url
-     */
-    function urlPicture ($aData, $bSubstituteNoImage = true) {
-        return $this->_image (BxPersonsConfig::$FIELD_PICTURE, BxPersonsConfig::$OBJECT_IMAGES_TRANSCODER_PICTURE, 'no-picture-preview.png', $aData, $bSubstituteNoImage);
-    }
-
-    /**
-     * Get profile cover image url
-     */
-    function urlCover ($aData, $bSubstituteNoImage = true) {
-        return $this->_image (BxPersonsConfig::$FIELD_COVER, BxPersonsConfig::$OBJECT_IMAGES_TRANSCODER_COVER, 'no-picture-cover.png', $aData, $bSubstituteNoImage);
-    }
-
-    /**
-     * Get profile picture icon url
-     */
-    function _image ($sField, $sTranscodeObject, $sNoImage, $aData, $bSubstituteNoImage = true) {
-        $sImageUrl = false;
-        if ($aData[$sField]) {
-            bx_import('BxDolImageTranscoder');                    
-            $oImagesTranscoder = BxDolImageTranscoder::getObjectInstance($sTranscodeObject);
-            if ($oImagesTranscoder)
-                $sImageUrl = $oImagesTranscoder->getImageUrl($aData[$sField]);
-        }
-        return $bSubstituteNoImage && !$sImageUrl? $this->getImageUrl($sNoImage) : $sImageUrl;
+class BxPersonsTemplate extends BxBaseModProfileTemplate 
+{
+    function __construct(&$oConfig, &$oDb) 
+    {
+        $this->MODULE = 'bx_persons';
+        parent::__construct($oConfig, $oDb);
     }
 }
 

+ 0 - 43
modules/boonex/persons/classes/BxPersonsUploader.php

@@ -1,43 +0,0 @@
-<?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    Persons Persons
- * @ingroup     DolphinModules
- *
- * @{
- */
-
-bx_import('BxTemplUploaderSimple');
-
-/**
- * Person uploader for avatar and cover images
- */
-class BxPersonsUploader extends BxTemplUploaderSimple {
-
-    protected $_iAccountProfileId;
-
-    public function __construct($aObject, $sStorageObject, $sUniqId) {
-        parent::__construct($aObject, $sStorageObject, $sUniqId);
-
-        bx_import('BxDolProfile');
-        $oAccountProfile = BxDolProfile::getInstanceAccountProfile();
-        $this->_iAccountProfileId = $oAccountProfile->id();
-    }
-
-    public function getGhosts($iProfileId, $sFormat, $sImagesTranscoder = false, $iContentId = false) {
-        return parent::getGhosts($this->_iAccountProfileId, $sFormat, $sImagesTranscoder, $iContentId);
-    }
-
-    public function deleteGhost($iFileId, $iProfileId) {
-        return parent::deleteGhost($iFileId, $this->_iAccountProfileId);
-    }
-
-    public function handleUploads ($iProfileId, $mixedFiles, $isMultiple = true, $iContentId = false) {
-        parent::handleUploads ($this->_iAccountProfileId, $mixedFiles, $isMultiple, $iContentId);
-    }
-
-}
-
-/** @} */

+ 3 - 6
modules/boonex/persons/install/langs/en.xml

@@ -32,10 +32,6 @@
 	<string name="_bx_persons_form_person_input_delete_confirm"><![CDATA[I am sure I want to delete this profile]]></string>
 	<string name="_bx_persons_form_person_input_delete_confirm_info"><![CDATA[This action can not be undone.]]></string>
 	<string name="_bx_persons_form_person_input_delete_confirm_error"><![CDATA[Please check this checkbox if you really want to delete your profile.]]></string>
-    <string name="_bx_persons_form_person_input_picture_txt_new"><![CDATA[New Picture]]></string>
-    <string name="_bx_persons_form_person_input_picture_txt_discard"><![CDATA[Discard]]></string>
-    <string name="_bx_persons_form_person_input_picture_txt_current"><![CDATA[Current Picture]]></string>
-    <string name="_bx_persons_form_person_input_picture_txt_delete"><![CDATA[Delete]]></string>
 
 	<string name="_bx_persons_acl_action_create_profile"><![CDATA[Create Person's Profile]]></string>
 	<string name="_bx_persons_acl_action_delete_profile"><![CDATA[Delete Person's Profile]]></string>
@@ -52,7 +48,10 @@
 	<string name="_bx_persons_page_title_delete_profile"><![CDATA[Delete Profile]]></string>
 	<string name="_bx_persons_page_title_sys_view_profile"><![CDATA[View Person's Profile]]></string>
 	<string name="_bx_persons_page_title_view_profile"><![CDATA[{display_name}]]></string>
+	<string name="_bx_persons_page_title_browse"><![CDATA[Persons]]></string>
 	<string name="_bx_persons_page_title_browse_recent"><![CDATA[Persons]]></string>
+	<string name="_bx_persons_page_title_browse_connections"><![CDATA[{0} connections]]></string>
+	<string name="_bx_persons_page_title_browse_connections_mutual"><![CDATA[{0} and {1} mutual connections]]></string>
 	<string name="_bx_persons_page_title_sys_profile_friends"><![CDATA[Friends]]></string>
 	<string name="_bx_persons_page_title_profile_friends"><![CDATA[Friends]]></string>
 	<string name="_bx_persons_page_title_sys_profile_info"><![CDATA[Profile Info]]></string>
@@ -110,8 +109,6 @@
     <string name="_bx_persons_txt_friend_pending_initiator"><![CDATA[Your friend request to this profile is awaiting confirmation.]]></string>
     <string name="_bx_persons_txt_friend_pending_content"><![CDATA[You have pending friend request from this profile - <a href="javascript:void(0);" onclick="bx_conn_action('sys_profiles_friends', 'add', '{profile_id}')">Accept</a> or <a href="javascript:void(0);" onclick="bx_conn_action('sys_profiles_friends', 'reject', '{profile_id}')">Reject</a>?]]></string>
 
-    <string name="_bx_persons_txt_change_image"><![CDATA[Change Picure]]></string>
-    <string name="_bx_persons_txt_no_picture_uploaded"><![CDATA[No picture uploaded]]></string>
     <string name="_bx_persons_txt_n_friends"><![CDATA[{0} friends]]></string>
     <string name="_bx_persons_txt_n_mutual_friends"><![CDATA[{0} mutual friends]]></string>
     <string name="_bx_persons_txt_one_mutual_friend"><![CDATA[<a href="{0}">{1}</a> mutual friend]]></string>

+ 0 - 4
modules/boonex/persons/install/sql/disable.sql

@@ -18,10 +18,6 @@ DELETE FROM `sys_transcoder_images_files` WHERE `transcoder_object` IN('bx_perso
 -- TODO: delete resized picture files as well
 TRUNCATE TABLE `bx_persons_pictures_resized`; 
 
--- UPLOADERS
-
-DELETE FROM `sys_objects_uploader` WHERE `object` IN('bx_persons_avatar', 'bx_persons_cover');
-
 -- PAGES
 
 DELETE FROM `sys_objects_page` WHERE `module` = 'bx_persons';

+ 21 - 27
modules/boonex/persons/install/sql/enable.sql

@@ -42,12 +42,6 @@ INSERT INTO `sys_transcoder_images_filters` (`transcoder_object`, `filter`, `fil
 ('bx_persons_cover', 'Resize', 'a:4:{s:1:"w";s:4:"1024";s:1:"h";s:4:"1024";s:13:"square_resize";s:1:"1";s:10:"force_type";s:3:"jpg";}', '0'),
 ('bx_persons_cover_thumb', 'Resize', 'a:4:{s:1:"w";s:2:"48";s:1:"h";s:2:"48";s:13:"square_resize";s:1:"1";s:10:"force_type";s:3:"jpg";}', '0');
 
--- UPLOADERS
-
-INSERT INTO `sys_objects_uploader` (`object`, `active`, `override_class_name`, `override_class_file`) VALUES
-('bx_persons_avatar', 1, 'BxPersonsUploader', 'modules/boonex/persons/classes/BxPersonsUploader.php'),
-('bx_persons_cover', 1, 'BxPersonsUploader', 'modules/boonex/persons/classes/BxPersonsUploader.php');
-
 -- PAGES
 
 --
@@ -57,61 +51,61 @@ INSERT INTO `sys_objects_page`(`object`, `uri`, `title_system`, `title`, `module
 ('bx_persons_create_profile', 'create-persons-profile', '_bx_persons_page_title_sys_create_profile', '_bx_persons_page_title_create_profile', 'bx_persons', 5, 2147483647, 1, 'page.php?i=create-persons-profile', '', '', '', 0, 1, 0, '', '');
 
 INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES 
-('bx_persons_create_profile', 1, 'bx_persons', '_bx_persons_page_block_title_create_profile', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:10:\"bx_persons\";s:6:\"method\";s:14:\"create_profile\";}', 0, 1, 1);
+('bx_persons_create_profile', 1, 'bx_persons', '_bx_persons_page_block_title_create_profile', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:10:\"bx_persons\";s:6:\"method\";s:13:\"entity_create\";}', 0, 1, 1);
 
 --
 -- Dumping data for 'bx_persons_view_profile' page
 --
 INSERT INTO `sys_objects_page`(`object`, `uri`, `title_system`, `title`, `module`, `layout_id`, `visible_for_levels`, `visible_for_levels_editable`, `url`, `meta_description`, `meta_keywords`, `meta_robots`, `cache_lifetime`, `cache_editable`, `deletable`, `override_class_name`, `override_class_file`) VALUES 
-('bx_persons_view_profile', 'view-persons-profile', '_bx_persons_page_title_sys_view_profile', '_bx_persons_page_title_view_profile', 'bx_persons', 10, 2147483647, 1, 'page.php?i=view-persons-profile', '', '', '', 0, 1, 0, 'BxPersonsPageProfile', 'modules/boonex/persons/classes/BxPersonsPageProfile.php');
+('bx_persons_view_profile', 'view-persons-profile', '_bx_persons_page_title_sys_view_profile', '_bx_persons_page_title_view_profile', 'bx_persons', 10, 2147483647, 1, 'page.php?i=view-persons-profile', '', '', '', 0, 1, 0, 'BxPersonsPageEntry', 'modules/boonex/persons/classes/BxPersonsPageEntry.php');
 
 INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES 
-('bx_persons_view_profile', 1, 'bx_persons', '_bx_persons_page_block_title_profile_actions', 3, 2147483647, 'service', 'a:2:{s:6:\"module\";s:10:\"bx_persons\";s:6:\"method\";s:15:\"profile_actions\";}', 0, 0, 0),
+('bx_persons_view_profile', 1, 'bx_persons', '_bx_persons_page_block_title_profile_actions', 3, 2147483647, 'service', 'a:2:{s:6:\"module\";s:10:\"bx_persons\";s:6:\"method\";s:14:\"entity_actions\";}', 0, 0, 0),
 ('bx_persons_view_profile', 1, 'bx_persons', '_bx_persons_page_block_title_profile_cover', 3, 2147483647, 'service', 'a:2:{s:6:\"module\";s:10:\"bx_persons\";s:6:\"method\";s:13:\"profile_cover\";}', 0, 0, 1),
-('bx_persons_view_profile', 2, 'bx_persons', '_bx_persons_page_block_title_profile_info', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:10:\"bx_persons\";s:6:\"method\";s:12:\"profile_info\";}', 0, 0, 0),
+('bx_persons_view_profile', 2, 'bx_persons', '_bx_persons_page_block_title_profile_info', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:10:\"bx_persons\";s:6:\"method\";s:11:\"entity_info\";}', 0, 0, 0),
 ('bx_persons_view_profile', 3, 'bx_persons', '_bx_persons_page_block_title_profile_friends', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:10:\"bx_persons\";s:6:\"method\";s:15:\"profile_friends\";}', 0, 0, 0);
 
 --
 -- Dumping data for 'bx_persons_edit_profile' page
 --
 INSERT INTO `sys_objects_page`(`object`, `uri`, `title_system`, `title`, `module`, `layout_id`, `visible_for_levels`, `visible_for_levels_editable`, `url`, `meta_description`, `meta_keywords`, `meta_robots`, `cache_lifetime`, `cache_editable`, `deletable`, `override_class_name`, `override_class_file`) VALUES 
-('bx_persons_edit_profile', 'edit-persons-profile', '_bx_persons_page_title_sys_edit_profile', '_bx_persons_page_title_edit_profile', 'bx_persons', 5, 2147483647, 1, 'page.php?i=edit-persons-profile', '', '', '', 0, 1, 0, 'BxPersonsPageProfile', 'modules/boonex/persons/classes/BxPersonsPageProfile.php');
+('bx_persons_edit_profile', 'edit-persons-profile', '_bx_persons_page_title_sys_edit_profile', '_bx_persons_page_title_edit_profile', 'bx_persons', 5, 2147483647, 1, 'page.php?i=edit-persons-profile', '', '', '', 0, 1, 0, 'BxPersonsPageEntry', 'modules/boonex/persons/classes/BxPersonsPageEntry.php');
 
 INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES 
-('bx_persons_edit_profile', 1, 'bx_persons', '_bx_persons_page_block_title_edit_profile', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:10:\"bx_persons\";s:6:\"method\";s:12:\"edit_profile\";}', 0, 0, 0);
+('bx_persons_edit_profile', 1, 'bx_persons', '_bx_persons_page_block_title_edit_profile', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:10:\"bx_persons\";s:6:\"method\";s:11:\"entity_edit\";}', 0, 0, 0);
 
 --
 -- Dumping data for 'bx_persons_edit_profile_cover' page
 --
 INSERT INTO `sys_objects_page`(`object`, `uri`, `title_system`, `title`, `module`, `layout_id`, `visible_for_levels`, `visible_for_levels_editable`, `url`, `meta_description`, `meta_keywords`, `meta_robots`, `cache_lifetime`, `cache_editable`, `deletable`, `override_class_name`, `override_class_file`) VALUES 
-('bx_persons_edit_profile_cover', 'edit-persons-cover', '_bx_persons_page_title_sys_edit_profile_cover', '_bx_persons_page_title_edit_profile_cover', 'bx_persons', 5, 2147483647, 1, 'page.php?i=edit-persons-cover', '', '', '', 0, 1, 0, 'BxPersonsPageProfile', 'modules/boonex/persons/classes/BxPersonsPageProfile.php');
+('bx_persons_edit_profile_cover', 'edit-persons-cover', '_bx_persons_page_title_sys_edit_profile_cover', '_bx_persons_page_title_edit_profile_cover', 'bx_persons', 5, 2147483647, 1, 'page.php?i=edit-persons-cover', '', '', '', 0, 1, 0, 'BxPersonsPageEntry', 'modules/boonex/persons/classes/BxPersonsPageEntry.php');
 
 INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES 
-('bx_persons_edit_profile_cover', 1, 'bx_persons', '_bx_persons_page_block_title_edit_profile_cover', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:10:\"bx_persons\";s:6:\"method\";s:10:\"edit_cover\";}', 0, 0, 0);
+('bx_persons_edit_profile_cover', 1, 'bx_persons', '_bx_persons_page_block_title_edit_profile_cover', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:10:\"bx_persons\";s:6:\"method\";s:17:\"entity_edit_cover\";}', 0, 0, 0);
 
 --
 -- Dumping data for 'bx_persons_delete_profile' page
 --
 INSERT INTO `sys_objects_page`(`object`, `uri`, `title_system`, `title`, `module`, `layout_id`, `visible_for_levels`, `visible_for_levels_editable`, `url`, `meta_description`, `meta_keywords`, `meta_robots`, `cache_lifetime`, `cache_editable`, `deletable`, `override_class_name`, `override_class_file`) VALUES 
-('bx_persons_delete_profile', 'delete-persons-profile', '_bx_persons_page_title_sys_delete_profile', '_bx_persons_page_title_delete_profile', 'bx_persons', 5, 2147483647, 1, 'page.php?i=delete-persons-profile', '', '', '', 0, 1, 0, 'BxPersonsPageProfile', 'modules/boonex/persons/classes/BxPersonsPageProfile.php');
+('bx_persons_delete_profile', 'delete-persons-profile', '_bx_persons_page_title_sys_delete_profile', '_bx_persons_page_title_delete_profile', 'bx_persons', 5, 2147483647, 1, 'page.php?i=delete-persons-profile', '', '', '', 0, 1, 0, 'BxPersonsPageEntry', 'modules/boonex/persons/classes/BxPersonsPageEntry.php');
 
 INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES 
-('bx_persons_delete_profile', 1, 'bx_persons', '_bx_persons_page_block_title_delete_profile', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:10:\"bx_persons\";s:6:\"method\";s:14:\"delete_profile\";}', 0, 0, 0);
+('bx_persons_delete_profile', 1, 'bx_persons', '_bx_persons_page_block_title_delete_profile', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:10:\"bx_persons\";s:6:\"method\";s:13:\"entity_delete\";}', 0, 0, 0);
 
 --
 -- Dumping data for 'bx_persons_profile_info' page
 --
 INSERT INTO `sys_objects_page`(`object`, `uri`, `title_system`, `title`, `module`, `layout_id`, `visible_for_levels`, `visible_for_levels_editable`, `url`, `meta_description`, `meta_keywords`, `meta_robots`, `cache_lifetime`, `cache_editable`, `deletable`, `override_class_name`, `override_class_file`) VALUES 
-('bx_persons_profile_info', 'persons-profile-info', '_bx_persons_page_title_sys_profile_info', '_bx_persons_page_title_profile_info', 'bx_persons', 5, 2147483647, 1, 'page.php?i=persons-profile-info', '', '', '', 0, 1, 0, 'BxPersonsPageProfile', 'modules/boonex/persons/classes/BxPersonsPageProfile.php');
+('bx_persons_profile_info', 'persons-profile-info', '_bx_persons_page_title_sys_profile_info', '_bx_persons_page_title_profile_info', 'bx_persons', 5, 2147483647, 1, 'page.php?i=persons-profile-info', '', '', '', 0, 1, 0, 'BxPersonsPageEntry', 'modules/boonex/persons/classes/BxPersonsPageEntry.php');
 
 INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES 
-('bx_persons_profile_info', 1, 'bx_persons', '_bx_persons_page_block_title_profile_info', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:10:\"bx_persons\";s:6:\"method\";s:12:\"profile_info\";}', 0, 0, 1);
+('bx_persons_profile_info', 1, 'bx_persons', '_bx_persons_page_block_title_profile_info', 11, 2147483647, 'service', 'a:2:{s:6:\"module\";s:10:\"bx_persons\";s:6:\"method\";s:11:\"entity_info\";}', 0, 0, 1);
 
 --
 -- Dumping data for 'bx_persons_profile_friends' page
 --
 INSERT INTO `sys_objects_page`(`object`, `uri`, `title_system`, `title`, `module`, `layout_id`, `visible_for_levels`, `visible_for_levels_editable`, `url`, `meta_description`, `meta_keywords`, `meta_robots`, `cache_lifetime`, `cache_editable`, `deletable`, `override_class_name`, `override_class_file`) VALUES 
-('bx_persons_profile_friends', 'persons-profile-friends', '_bx_persons_page_title_sys_profile_friends', '_bx_persons_page_title_profile_friends', 'bx_persons', 5, 2147483647, 1, 'page.php?i=persons-profile-friends', '', '', '', 0, 1, 0, 'BxPersonsPageProfile', 'modules/boonex/persons/classes/BxPersonsPageProfile.php');
+('bx_persons_profile_friends', 'persons-profile-friends', '_bx_persons_page_title_sys_profile_friends', '_bx_persons_page_title_profile_friends', 'bx_persons', 5, 2147483647, 1, 'page.php?i=persons-profile-friends', '', '', '', 0, 1, 0, 'BxPersonsPageEntry', 'modules/boonex/persons/classes/BxPersonsPageEntry.php');
 
 INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES 
 ('bx_persons_profile_friends', 1, 'bx_persons', '_bx_persons_page_block_title_profile_friends', 11, 2147483647, 'service', 'a:3:{s:6:\"module\";s:6:\"system\";s:6:\"method\";s:17:\"connections_table\";s:5:\"class\";s:23:\"TemplServiceConnections\";}', 0, 0, 1);
@@ -119,7 +113,7 @@ INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title`, `designbo
 
 -- Homepage
 INSERT INTO `sys_pages_blocks` (`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES
-('sys_home', 0, 'bx_persons', '_bx_persons_page_block_title_latest_persons', 0, 2147483647, 'service', 'a:2:{s:6:"module";s:10:"bx_persons";s:6:"method";s:21:"browse_recent_persons";}', 0, 1, 0);
+('sys_home', 0, 'bx_persons', '_bx_persons_page_block_title_latest_persons', 0, 2147483647, 'service', 'a:2:{s:6:"module";s:10:"bx_persons";s:6:"method";s:22:"browse_recent_profiles";}', 0, 1, 0);
 
 -- MENU
 
@@ -136,7 +130,7 @@ INSERT INTO `sys_menu_items` (`set_name`, `module`, `name`, `title_system`, `tit
 -- Dumping data for 'bx_persons_view_actions' menu
 --
 INSERT INTO `sys_objects_menu`(`object`, `title`, `set_name`, `module`, `template_id`, `deletable`, `active`, `override_class_name`, `override_class_file`) VALUES 
-('bx_persons_view_actions', '_bx_persons_menu_title_view_person_actions', 'bx_persons_view_actions', 'bx_persons', 9, 0, 1, 'BxPersonsMenuViewPerson', 'modules/boonex/persons/classes/BxPersonsMenuViewPerson.php');
+('bx_persons_view_actions', '_bx_persons_menu_title_view_person_actions', 'bx_persons_view_actions', 'bx_persons', 9, 0, 1, 'BxPersonsMenuView', 'modules/boonex/persons/classes/BxPersonsMenuView.php');
 
 INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
 ('bx_persons_view_actions', 'bx_persons', '_bx_persons_menu_set_title_view_person_actions', 0);
@@ -150,7 +144,7 @@ INSERT INTO `sys_menu_items`(`set_name`, `module`, `name`, `title_system`, `titl
 -- Dumping data for 'bx_persons_view_actions_more' menu
 --
 INSERT INTO `sys_objects_menu`(`object`, `title`, `set_name`, `module`, `template_id`, `deletable`, `active`, `override_class_name`, `override_class_file`) VALUES 
-('bx_persons_view_actions_more', '_bx_persons_menu_title_view_person_actions_more', 'bx_persons_view_actions_more', 'bx_persons', 6, 0, 1, 'BxPersonsMenuViewPerson', 'modules/boonex/persons/classes/BxPersonsMenuViewPerson.php');
+('bx_persons_view_actions_more', '_bx_persons_menu_title_view_person_actions_more', 'bx_persons_view_actions_more', 'bx_persons', 6, 0, 1, 'BxPersonsMenuView', 'modules/boonex/persons/classes/BxPersonsMenuView.php');
 
 INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
 ('bx_persons_view_actions_more', 'bx_persons', '_bx_persons_menu_set_title_view_person_actions_more', 0);
@@ -166,7 +160,7 @@ INSERT INTO `sys_menu_items`(`set_name`, `module`, `name`, `title_system`, `titl
 -- Dumping data for 'bx_persons_view_submenu' menu
 --
 INSERT INTO `sys_objects_menu`(`object`, `title`, `set_name`, `module`, `template_id`, `deletable`, `active`, `override_class_name`, `override_class_file`) VALUES 
-('bx_persons_view_submenu', '_bx_persons_menu_title_view_person_submenu', 'bx_persons_view_submenu', 'bx_persons', 8, 0, 1, 'BxPersonsMenuViewPerson', 'modules/boonex/persons/classes/BxPersonsMenuViewPerson.php');
+('bx_persons_view_submenu', '_bx_persons_menu_title_view_person_submenu', 'bx_persons_view_submenu', 'bx_persons', 8, 0, 1, 'BxPersonsMenuView', 'modules/boonex/persons/classes/BxPersonsMenuView.php');
 
 INSERT INTO `sys_menu_sets`(`set_name`, `module`, `title`, `deletable`) VALUES 
 ('bx_persons_view_submenu', 'bx_persons', '_bx_persons_menu_set_title_view_person_submenu', 0);
@@ -191,19 +185,19 @@ INSERT INTO `sys_menu_items` (`set_name`, `module`, `name`, `title_system`, `tit
 -- ACL
 
 INSERT INTO `sys_acl_actions` (`Module`, `Name`, `AdditionalParamName`, `Title`, `Desc`, `Countable`, `DisabledForLevels`) VALUES
-('bx_persons', 'create person profile', NULL, '_bx_persons_acl_action_create_profile', '', 1, 1);
+('bx_persons', 'create entry', NULL, '_bx_persons_acl_action_create_profile', '', 1, 1);
 SET @iIdActionProfileCreate = LAST_INSERT_ID();
 
 INSERT INTO `sys_acl_actions` (`Module`, `Name`, `AdditionalParamName`, `Title`, `Desc`, `Countable`, `DisabledForLevels`) VALUES
-('bx_persons', 'delete person profile', NULL, '_bx_persons_acl_action_delete_profile', '', 1, 1);
+('bx_persons', 'delete entry', NULL, '_bx_persons_acl_action_delete_profile', '', 1, 1);
 SET @iIdActionProfileDelete = LAST_INSERT_ID();
 
 INSERT INTO `sys_acl_actions` (`Module`, `Name`, `AdditionalParamName`, `Title`, `Desc`, `Countable`, `DisabledForLevels`) VALUES
-('bx_persons', 'view person profile', NULL, '_bx_persons_acl_action_view_profile', '', 1, 1);
+('bx_persons', 'view entry', NULL, '_bx_persons_acl_action_view_profile', '', 1, 1);
 SET @iIdActionProfileView = LAST_INSERT_ID();
 
 INSERT INTO `sys_acl_actions` (`Module`, `Name`, `AdditionalParamName`, `Title`, `Desc`, `Countable`, `DisabledForLevels`) VALUES
-('bx_persons', 'edit any person profile', NULL, '_bx_persons_acl_action_edit_any_profile', '', 1, 1);
+('bx_persons', 'edit any entry', NULL, '_bx_persons_acl_action_edit_any_profile', '', 1, 1);
 SET @iIdActionProfileEditAny = LAST_INSERT_ID();
 
 

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

@@ -57,7 +57,7 @@ CREATE TABLE `bx_persons_views_track` (
 
 -- FORMS
 INSERT INTO `sys_objects_form`(`object`, `module`, `title`, `action`, `form_attrs`, `table`, `key`, `uri`, `uri_title`, `submit_name`, `params`, `deletable`, `active`, `override_class_name`, `override_class_file`) VALUES 
-('bx_person', 'bx_persons', '_bx_persons_form_person', '', 'a:1:{s:7:\"enctype\";s:19:\"multipart/form-data\";}', 'bx_persons_data', 'id', '', '', 'do_submit', '', 0, 1, 'BxPersonsFormPerson', 'modules/boonex/persons/classes/BxPersonsFormPerson.php');
+('bx_person', 'bx_persons', '_bx_persons_form_person', '', 'a:1:{s:7:\"enctype\";s:19:\"multipart/form-data\";}', 'bx_persons_data', 'id', '', '', 'do_submit', '', 0, 1, 'BxPersonsFormEntry', 'modules/boonex/persons/classes/BxPersonsFormEntry.php');
 
 INSERT INTO `sys_form_displays`(`object`, `display_name`, `module`, `view_mode`, `title`) VALUES 
 ('bx_person', 'bx_person_add', 'bx_persons', 0, '_bx_persons_form_person_display_add'),

+ 0 - 30
modules/boonex/persons/js/forms.js

@@ -1,30 +0,0 @@
-
-function bx_persons_action_with_ghost (sAction, iFileId, iContentId, oUploader, sFieldName) {
-    bx_loading("bx-uploader-file-" + iFileId, true);
-    $.post(sUrlRoot + "modules/?r=persons/" + sAction + "/" + iFileId + "/" + iContentId + "/" + sFieldName, function(s) {
-        bx_loading("bx-uploader-file-" + iFileId, false);
-        if (s.length)
-            alert(s);
-        else
-            oUploader.restoreGhosts();
-    });
-}
-
-function bx_persons_discard_ghost (iFileId, iContentId, oUploader, sFieldName) {
-    bx_persons_action_with_ghost ('discard_ghost', iFileId, iContentId, oUploader, sFieldName);
-}
-
-function bx_persons_delete_ghost (iFileId, iContentId, oUploader, sFieldName) {
-    bx_persons_action_with_ghost ('delete_ghost', iFileId, iContentId, oUploader, sFieldName);
-}
-
-function bx_persons_toggle_draft (iFileId, iCurrentFileId, sFieldName) {
-    if (iFileId == iCurrentFileId) {
-        $("#bx-form-element-" + sFieldName + " .bx-uploader-ghost-current").show();
-        $("#bx-form-element-" + sFieldName + " .bx-uploader-ghost-draft").hide();
-    } else {
-        $("#bx-form-element-" + sFieldName + " .bx-uploader-ghost-current").hide();
-        $("#bx-form-element-" + sFieldName + " .bx-uploader-ghost-draft").show();
-    }
-}
-

+ 0 - 1
modules/boonex/persons/template/block_picture.html

@@ -1 +0,0 @@
-<div class="bx-persons-preview"><img class="bx-def-round-corners" src="__url__" /></div>

+ 1 - 12
modules/boonex/persons/template/cover.html

@@ -1,12 +1 @@
-
-<div class="bx-persons-cover">
-    <a class="bx-persons-cover-image bx-def-round-corners bx-def-border" href="__cover_href__" onclick="$('#bx-persons-popup-cover').dolPopupImage('__cover_url__', this)" style="background-image:url(__cover_url__)">&nbsp;</a>
-    <div class="bx-persons-cover-info bx-def-unit bx-def-padding">
-        <a href="__picture_href__" onclick="$('#bx-persons-popup-picture').dolPopupImage('__picture_url__', $(this).parent())"><img class="bx-def-margin-right bx-def-ava bx-def-ava-size" src="__picture_avatar_url__" /></a>
-        <h1 class="bx-def-unit-info bx-def-margin-sec-bottom bx-def-margin-sec-top bx-def-font-contrasted">__title__</h1>
-    </div>
-</div>
-
-__cover_popup__
-__picture_popup__
-
+<bx_include_base:../modules/base/profile/template/cover.html />

+ 1 - 85
modules/boonex/persons/template/css/main.css

@@ -1,85 +1 @@
-
-
-/* browse unit */
-
-.bx-persons-unit {
-    width:188px;
-    width:11.8rem;
-    float:left;
-}
-
-.bx-persons-unit div {
-    width:140px;
-    width:8.8rem;
-}
-
-/* view content */
-
-.bx-persons-preview {
-    max-width:278px;
-    max-width:17.375rem;
-    text-align:center;
-}
-.bx-persons-preview img {
-    width:100%;
-}
-
-/* profile cover */
-
-.bx-persons-cover {
-    position:relative;
-    height:320px;
-    height:20rem;
-
-    -moz-box-sizing: border-box;
-    -ms-box-sizing: border-box;
-    -webkit-box-sizing: border-box;
-    box-sizing: border-box;
-}
-
-a.bx-persons-cover-image:hover,
-.bx-persons-cover-image {
-    position:absolute;
-    width:100%;
-    height:100%;
-    text-decoration:none;
-
-    background: url(../images/no-picture-cover.png) no-repeat center center; 
-    -webkit-background-size: cover;
-    -moz-background-size: cover;
-    -o-background-size: cover;
-    background-size: cover;
-    background-color: #eee;
-}
-
-.bx-persons-cover-info {
-    position:absolute;
-    bottom:0;
-    left:0;
-}
-
-.bx-persons-cover-info img,
-.bx-persons-cover-info h1 {
-    vertical-align:bottom;
-}
-
-.bx-persons-cover-info img {
-    border:2px solid #fff;
-    border:0.15rem solid #fff;
-}
-
-.bx-persons-cover-info h1.bx-def-unit-info {
-    padding:0;
-    text-shadow: 0px 0px 0.125rem #000;
-    line-height:normal;
-}
-
-.bx-persons-popup-wrapper {
-    position:relative;
-}
-
-.bx-persons-popup-btn {
-    position:absolute;
-    top:0;
-    right:0;
-}
+@import url(../../../../base/profile/template/css/main.css);

+ 0 - 17
modules/boonex/persons/template/form_ghost_template.html

@@ -1,17 +0,0 @@
-<div id="bx-uploader-file-{file_id}" class="bx-uploader-ghost bx-def-margin-sec-top">
-    <input type="hidden" name="__name__" value="{file_id}" />
-    <img src="{file_icon}" class="bx-def-margin-sec-right" style="vertical-align:middle;" />
-    <span class="bx-uploader-ghost-draft">
-        <bx_text:_bx_persons_form_person_input_picture_txt_new />
-        <a class="bx-btn bx-btn-small" style="float:none; display:inline-block;" href="javascript:void(0);" onclick="bx_persons_discard_ghost({file_id}, __content_id__, {js_instance_name}, '__name__');"><bx_text:_bx_persons_form_person_input_picture_txt_discard /></a>
-    </span>
-    <span class="bx-uploader-ghost-current" style="display:none;">
-        <bx_text:_bx_persons_form_person_input_picture_txt_current />
-        <bx_if:not_required>
-            <a class="bx-btn bx-btn-small" style="float:none; display:inline-block;" href="javascript:void(0);" onclick="bx_persons_delete_ghost({file_id}, __content_id__, {js_instance_name}, '__name__');"><bx_text:_bx_persons_form_person_input_picture_txt_delete /></a>
-        </bx_if:not_required>
-    </span>
-    <script>
-        bx_persons_toggle_draft({file_id}, __current_picture_id__, '__name__');
-    </script>
-</div>

+ 1 - 6
modules/boonex/persons/template/image_popup.html

@@ -1,6 +1 @@
-<div class="bx-persons-popup-wrapper">
-    <bx_if:owner>
-        <div class="bx-persons-popup-btn bx-def-padding"><a class="bx-btn" href="__change_image_url__"><bx_text:_bx_persons_txt_change_image /></a></div>
-    </bx_if:owner>
-    <img class="bx-persons-popup-image" src="__image_url__" />
-</div>
+<bx_include_base:../modules/base/profile/template/image_popup.html />

+ 1 - 6
modules/boonex/persons/template/picture_preview.html

@@ -1,6 +1 @@
-<bx_if:picture>
-    <img class="bx-def-round-corners" src="__picture_url__" />
-</bx_if:picture>
-<bx_if:no_picture>
-    <i class="bx-def-font-small"><bx_text:_bx_persons_txt_no_picture_uploaded /></i>
-</bx_if:no_picture>
+<bx_include_base:../modules/base/profile/template/picture_preview.html />

+ 1 - 5
modules/boonex/persons/template/unit.html

@@ -1,5 +1 @@
-
-<div class="bx-persons-unit bx-def-unit bx-def-margin-bottom bx-def-margin-sec-right">
-    <a href="__content_url__"><img class="bx-def-thumb bx-def-thumb-size" src="__thumb_url__" /></a><div class="bx-def-unit-info bx-def-thumb-size-max-height bx-def-padding-sec-left"><a href="__content_url__">__title__</a></div>
-</div>
-
+<bx_include_base:../modules/base/profile/template/unit.html />