<?php
/***************************************************************************
*                            Dolphin Smart Community Builder
*                              -------------------
*     begin                : Mon Mar 23 2006
*     copyright            : (C) 2007 BoonEx Group
*     website              : http://www.boonex.com
* This file is part of Dolphin - Smart Community Builder
*
* Dolphin is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the
* License, or  any later version.
*
* Dolphin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
* You should have received a copy of the GNU General Public License along with Dolphin,
* see license.txt file; if not, write to marketing@boonex.com
***************************************************************************/

function bx_store_import ($sClassPostfix, $aModuleOverwright = array()) {
    global $aModule;
    $a = $aModuleOverwright ? $aModuleOverwright : $aModule;
    if (!$a || $a['uri'] != 'store') {
        $oMain = BxDolModule::getInstance('BxStoreModule');
        $a = $oMain->_aModule;
    }
    bx_import ($sClassPostfix, $a) ;
}

bx_import('BxDolPaginate');
bx_import('BxDolAlerts');
bx_import('BxDolTwigModule');

define ('BX_STORE_PHOTOS_CAT', 'Store');
define ('BX_STORE_PHOTOS_TAG', 'store');

define ('BX_STORE_VIDEOS_CAT', 'Store');
define ('BX_STORE_VIDEOS_TAG', 'store');

define ('BX_STORE_FILES_CAT', 'Store');
define ('BX_STORE_FILES_TAG', 'store');

/**
 * Store module
 *
 * This module allow users to post products, 
 * other members can downoad them for free or some price.
 * Later customers can rate, comment and discuss products.
 * Product can have photos, videos and files.
 *
 * 
 *
 * Profile's Wall:
 * 'add product' event are displayed in profile's wall
 *
 *
 *
 * Spy:
 * The following qactivity is displayed for content_activity:
 * add - new product was created
 * change - product was chaned
 * rate - somebody rated product
 * commentPost - somebody posted review in product
 *
 *
 * 
 * Memberships/ACL:
 * store view product - BX_STORE_VIEW_PRODUCT
 * store browse - BX_STORE_BROWSE
 * store search - BX_STORE_SEARCH
 * store add product - BX_STORE_ADD_PRODUCT
 * store edit any product - BX_STORE_EDIT_ANY_PRODUCT
 * store delete any product - BX_STORE_DELETE_ANY_PRODUCT
 * store mark as featured - BX_STORE_MARK_AS_FEATURED
 * store approve aproduct - BX_STORE_APPROVE_PRODUCT
 * store broadcast message - BX_STORE_BROADCAST_MESSAGE
 *
 * 
 *
 * Service methods:
 *
 * Homepage block with different products
 * @see BxStoreModule::serviceHomepageBlock
 * BxDolService::call('store', 'homepage_block', array());
 *
 * Profile block with user's products
 * @see BxStoreModule::serviceProfileBlock
 * BxDolService::call('store', 'profile_block', array($iProfileId));
 *
 * Product's forum permissions (for internal usage only)
 * @see BxStoreModule::serviceGetForumPermission
 * BxDolService::call('store', 'get_forum_permission', array($iMemberId, $iForumId));
 *
 * Member menu item for store (for internal usage only)
 * @see BxStoreModule::serviceGetMemberMenuItem
 * BxDolService::call('store', 'get_member_menu_item', array());
 *
 *
 *
 * Alerts:
 * Alerts type/unit - 'bx_store'
 * The following alerts are rised
 *
 *  add - new product was added
 *      $iObjectId - product id
 *      $iSenderId - creator of product
 *      $aExtras['Status'] - status of added product
 *
 *  change - product's info was changed
 *      $iObjectId - product  id
 *      $iSenderId - editor user id
 *      $aExtras['Status'] - status of changed product
 *
 *  delete - product was deleted
 *      $iObjectId - product id
 *      $iSenderId - deleter user id
 *
 *  mark_as_featured - product was marked/unmarked as featured
 *      $iObjectId - product id
 *      $iSenderId - performer id
 *      $aExtras['Featured'] - 1 - if product was marked as featured and 0 - if product was removed from featured 
 *
 */
class BxStoreModule extends BxDolTwigModule {

    var $_oPrivacyProduct;
    var $_oPrivacyFile;

    var $_aQuickCache = array ();

    function BxStoreModule(&$aModule) {

        parent::BxDolTwigModule($aModule);        
        $this->_sFilterName = 'bx_store_filter';
        $this->_sPrefix = 'bx_store';

        bx_import ('PrivacyProduct', $aModule);
        bx_import ('PrivacyFile', $aModule);
        $this->_oPrivacyProduct = new BxStorePrivacyProduct($this);
        $this->_oPrivacyFile = new BxStorePrivacyFile($this);

        $GLOBALS['oBxStoreModule'] = &$this;
    }

    function actionHome () {
        parent::_actionHome(_t('_bx_store_page_title_home'));
    }

    function actionVideos ($sUri) {
        parent::_actionVideos ($sUri, _t('_bx_store_page_title_videos'));
    }

    function actionPhotos ($sUri) {
        parent::_actionPhotos ($sUri, _t('_bx_store_page_title_photos'));
    }

    function actionComments ($sUri) {
        parent::_actionComments ($sUri, _t('_bx_store_page_title_comments'));
    }

    function actionView ($sUri) {
        parent::_actionView ($sUri, _t('_bx_store_msg_pending_approval'));
    }

    function actionBroadcast ($iEntryId) {
        parent::_actionBroadcast ($iEntryId, _t('_bx_store_page_title_broadcast'), _t('_bx_store_msg_broadcast_no_recipients'), _t('_bx_store_msg_broadcast_message_sent'));
    }

    function actionCalendar ($iYear = '', $iMonth = '') {
        parent::_actionCalendar ($iYear, $iMonth, _t('_bx_store_page_title_calendar'));
    }

    function actionSearch ($sKeyword = '', $sCategory = '') {
        parent::_actionSearch ($sKeyword, $sCategory, _t('_bx_store_page_title_search'));
    }

    function actionAdd () {
        parent::_actionAdd (_t('_bx_store_page_title_add'));
    }

    function actionEdit ($iEntryId) {
        $this->_oTemplate->addCss ('form_field_product_files_choice.css');
        parent::_actionEdit ($iEntryId, _t('_bx_store_page_title_edit'));        
    }

    function actionDelete ($iEntryId) {
        parent::_actionDelete ($iEntryId, _t('_bx_store_msg_product_was_deleted'));
    }

    function actionMarkFeatured ($iEntryId) {
        parent::_actionMarkFeatured ($iEntryId, _t('_bx_store_msg_added_to_featured'), _t('_bx_store_msg_removed_from_featured'));
    }

    function actionSharePopup ($iEntryId) {
        parent::_actionSharePopup ($iEntryId, _t('_bx_store_cpation_share_product'));
    }

    function actionTags() {
        parent::_actionTags (_t('_bx_store_page_title_tags'));
    }    

    function actionCategories() {
        parent::_actionCategories (_t('_bx_store_page_title_categories'));
    }    

    function actionToggleProductFileVisibility ($iFileId) {

        $aFileInfo = $this->_oDb->getFileInfoByFileId ((int)$iFileId);
        if (!$aFileInfo) {
            echo _t ('_sys_request_page_not_found_cpt');
            exit;
        }

        if (!$this->_iProfileId || $aFileInfo['author_id'] != $this->_iProfileId) {
            echo _t ('_Access denied');
            exit;
        }

        if (false === ($iHidden = $this->_oDb->toggleProductFileVisibility ($aFileInfo['id']))) {
            echo _t ('_Error Occured');
            exit;
        }

        echo $iHidden ? _t ('_bx_store_product_file_hidden') : _t ('_bx_store_product_file_visible');
        exit;
    }

    function actionDownload ($iFileId) {

        $aFileInfo = $this->_oDb->getFileInfoByFileId ((int)$iFileId);

        if (!$aFileInfo) {
            $this->_oTemplate->displayPageNotFound ();
            exit;
        }

        if (!$this->isAllowedDownload ($aFileInfo)) {
            $this->_oTemplate->displayAccessDenied ();
            exit;
        }

        parent::_actionDownload($aFileInfo, 'media_id');
    }

    // ================================== external actions

    function serviceHomepageBlock () {

        if (!$this->_oDb->isAnyPublicContent())
            return '';
        
        bx_import ('PageMain', $this->_aModule);
        $o = new BxStorePageMain ($this);
        $o->sUrlStart = BX_DOL_URL_ROOT . '?';

        $sDefaultHomepageTab = $this->_oDb->getParam('bx_store_homepage_default_tab');

        $sBrowseMode = $sDefaultHomepageTab;
        switch ($_GET['bx_store_filter']) {
            case 'featured':
            case 'recent':
            case 'top':
            case 'popular':
            case 'free':
            case $sDefaultHomepageTab:            
                $sBrowseMode = $_GET['bx_store_filter'];
                break;
        }

        return $o->ajaxBrowse(
            $sBrowseMode,
            $this->_oDb->getParam('bx_store_perpage_homepage'), 
            array(
                _t('_bx_store_tab_featured') => array('href' => BX_DOL_URL_ROOT . '?bx_store_filter=featured', 'active' => 'featured' == $sBrowseMode, 'dynamic' => true),
                _t('_bx_store_tab_recent') => array('href' => BX_DOL_URL_ROOT . '?bx_store_filter=recent', 'active' => 'recent' == $sBrowseMode, 'dynamic' => true),
                _t('_bx_store_tab_top') => array('href' => BX_DOL_URL_ROOT . '?bx_store_filter=top', 'active' => 'top' == $sBrowseMode, 'dynamic' => true),
                _t('_bx_store_tab_popular') => array('href' => BX_DOL_URL_ROOT . '?bx_store_filter=popular', 'active' => 'popular' == $sBrowseMode, 'dynamic' => true),
                _t('_bx_store_tab_free') => array('href' => BX_DOL_URL_ROOT . '?bx_store_filter=free', 'active' => 'free' == $sBrowseMode, 'dynamic' => true),
            )
        );
    }

    function serviceProfileBlock ($iProfileId) {

        $aProfile = getProfileInfo($iProfileId);
        bx_import ('PageMain', $this->_aModule);
        $o = new BxStorePageMain ($this);        
        $o->sUrlStart = getProfileLink($aProfile['ID']) . '?';

        return $o->ajaxBrowse(
            'user', 
            $this->_oDb->getParam('bx_store_perpage_profile'), 
            array(),
            process_db_input ($aProfile['NickName'], BX_TAGS_NO_ACTION, BX_SLASHES_NO_ACTION),
            true,
            false
        );
    }

    function serviceGetMemberMenuItem () {
        parent::_serviceGetMemberMenuItem (_t('_bx_store'), _t('_bx_store'), 'store.png');
    }

    function serviceGetWallPost ($aEvent) {
        return parent::_serviceGetWallPost ($aEvent, _t('_bx_store_wall_object'), _t('_bx_store_wall_added_new'));
    }

    function serviceGetSpyPost($sAction, $iObjectId = 0, $iSenderId = 0, $aExtraParams = array()) {
        return parent::_serviceGetSpyPost($sAction, $iObjectId, $iSenderId, $aExtraParams, array(
            'add' => '_bx_store_spy_post',
            'change' => '_bx_store_spy_post_change',
            'rate' => '_bx_store_spy_rate',
            'commentPost' => '_bx_store_spy_comment',
        ));
    }

    function serviceGetSpyData () {        
        $aOld = parent::serviceGetSpyData ();
        $aNew =  array (
            'handlers' => array (),
            'alerts' => array (),
        );
        foreach ($aOld['handlers'] as $a) {
            if ('join' == $a['alert_action']) continue;
            $aNew['handlers'][] = $a;
        }
        foreach ($aOld['alerts'] as $a) {
            if ('join' == $a['action']) continue;
            $aNew['alerts'][] = $a;
        }                   
        return $aNew;
    }

    function serviceGetSubscriptionParams ($sAction, $iEntryId) {

        $a = array (
            'change' => _t('_bx_store_sbs_change'),
            'commentPost' => _t('_bx_store_sbs_comment'),
            'rate' => _t('_bx_store_sbs_rate'),
        );

        return parent::_serviceGetSubscriptionParams ($sAction, $iEntryId, $a);
    }

    function serviceGetItems($iVendorId) {	    
        $iVendorId = (int)$iVendorId;
	    if($iVendorId < 0) 
            return array();

        $aItems = $this->_oDb->getFilesByAuthor ($iVendorId);

	    $aResult = array();
        foreach($aItems as $aItem) {
            $aFile = BxDolService::call('files', 'get_file_array', array($aItem['media_id']), 'Search');
            if (!$aFile['date'])
                continue;           
            $aResult[] = array(
    	       'id' => $aItem['id'],
    	       'title' => $aItem['title'] . ' - ' . $aFile['title'] . ' / ' . $aItem['price'],
    	       'description' => $aItem['title'] . ' - ' . $aFile['title'],
    	       'url' => BX_DOL_URL_ROOT . $this->_oConfig->getBaseUri() . 'view/' . $aItem['uri'],
    	       'price' => $aItem['price'],
           );
        }

	    return $aResult;
    }

    function serviceGetCartItem($iClientId, $iItemId) {

        if (!$iItemId || !$iClientId)
            return array ();

        $aItem = $this->_oDb->getFileInfoByFileId ($iItemId);
        $aFile = BxDolService::call('files', 'get_file_array', array($aItem['media_id']), 'Search');
        if (!$aFile['date'])
            return array ();

        return array (
           'id' => $aItem['id'],
           'title' => $aItem['title'] . ' - ' . $aFile['title'],
           'description' => $aItem['title'] . ' - ' . $aFile['title'],
           'url' => BX_DOL_URL_ROOT . $this->_oConfig->getBaseUri() . 'view/' . $aItem['uri'],
           'price' => $aItem['price'],
        );
    }

    function serviceRegisterCartItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrderId) {

        $aItem = $this->_oDb->getFileInfoByFileId ($iItemId);
        $aFile = BxDolService::call('files', 'get_file_array', array($aItem['media_id']), 'Search');
        if (!$aFile['date'])
            return array ();

        if (!$this->_oDb->registerCustomer ($iClientId, $iItemId, $sOrderId, $iItemCount, time()))
            return array ();

        return array (
           'id' => $aItem['id'],
           'title' => $aItem['title'] . ' - ' . $aFile['title'],
           'description' => $aItem['title'] . ' - ' . $aFile['title'],
           'url' => BX_DOL_URL_ROOT . $this->_oConfig->getBaseUri() . 'view/' . $aItem['uri'],
           'price' => $aItem['price'],
        );
    }

    function serviceUnregisterCartItem($iClientId, $iSellerId, $iItemId, $iItemCount, $sOrderId) {
        return $this->_oDb->unregisterCustomer ($iClientId, $iItemId, $sOrderId);
    }

    function serviceDeleteProfileData ($iProfileId) {
        parent::serviceDeleteProfileData($iProfileId);
        
        // delete from list of customers
        $this->_oDb->removeCustomersFromAllEntries ($iProfileId);
    }

    // ================================== admin actions

    function actionAdministration ($sUrl = '') {

        if (!$this->isAdmin()) {
            $this->_oTemplate->displayAccessDenied ();
            return;
        }        

        $this->_oTemplate->pageStart();

        $aMenu = array(
            'pending_approval' => array(
                'title' => _t('_bx_store_menu_admin_pending_approval'), 
                'href' => BX_DOL_URL_ROOT . $this->_oConfig->getBaseUri() . 'administration/pending_approval', 
                '_func' => array ('name' => 'actionAdministrationManage', 'params' => array(false, 'administration/pending_approval')),
            ),
            'admin_entries' => array(
                'title' => _t('_bx_store_menu_admin_entries'), 
                'href' => BX_DOL_URL_ROOT . $this->_oConfig->getBaseUri() . 'administration/admin_entries',
                '_func' => array ('name' => 'actionAdministrationManage', 'params' => array(true, 'administration/admin_entries')),
            ),            
            'create' => array(
                'title' => _t('_bx_store_menu_admin_add_entry'), 
                'href' => BX_DOL_URL_ROOT . $this->_oConfig->getBaseUri() . 'administration/create',
                '_func' => array ('name' => 'actionAdministrationCreateEntry', 'params' => array()),
            ),
            'settings' => array(
                'title' => _t('_bx_store_menu_admin_settings'), 
                'href' => BX_DOL_URL_ROOT . $this->_oConfig->getBaseUri() . 'administration/settings',
                '_func' => array ('name' => 'actionAdministrationSettings', 'params' => array()),
            ),
        );

        if (empty($aMenu[$sUrl]))
            $sUrl = 'pending_approval';

        $aMenu[$sUrl]['active'] = 1;
        $sContent = call_user_func_array (array($this, $aMenu[$sUrl]['_func']['name']), $aMenu[$sUrl]['_func']['params']);

        echo $this->_oTemplate->adminBlock ($sContent, _t('_bx_store_page_title_administration'), $aMenu);
        $this->_oTemplate->addCssAdmin ('admin.css');
        $this->_oTemplate->addCssAdmin ('unit.css');
        $this->_oTemplate->addCssAdmin ('main.css');
        $this->_oTemplate->addCssAdmin ('forms_extra.css'); 
        $this->_oTemplate->addCssAdmin ('forms_adv.css');        
        $this->_oTemplate->pageCodeAdmin (_t('_bx_store_page_title_administration'));
    }

    function actionAdministrationSettings () {
        return parent::_actionAdministrationSettings ('Store');
    }

    function actionAdministrationManage ($isAdminEntries = false, $sUrl = '') {
        return parent::_actionAdministrationManage ($isAdminEntries, '_bx_store_admin_delete', '_bx_store_admin_activate', $sUrl);
    }

    // ================================== events


    // ================================== permissions
    
    function isEntryAdmin($aDataEntry, $iIdProfile = 0) {
        if (!$iIdProfile)
            $iIdProfile = $this->_iProfileId;
        return ($this->isAdmin() || $aDataEntry['author_id'] == $iIdProfile);
    }

    function isAllowedView ($aDataEntry, $isPerformAction = false) {

        // admin and owner always have access
        if ($this->isAdmin() || $aDataEntry['author_id'] == $this->_iProfileId) 
            return true;

        // check admin acl
        $this->_defineActions();
		$aCheck = checkAction($this->_iProfileId, BX_STORE_VIEW_PRODUCT, $isPerformAction);
        if ($aCheck[CHECK_ACTION_RESULT] != CHECK_ACTION_RESULT_ALLOWED)
            return false;

        // check user group
	    return $this->_oPrivacyProduct->check('view_product', $aDataEntry['id'], $this->_iProfileId); 
    }

    function isAllowedBrowse ($isPerformAction = false) {
        if ($this->isAdmin()) 
            return true;
        $this->_defineActions();
		$aCheck = checkAction($this->_iProfileId, BX_STORE_BROWSE, $isPerformAction);
        return $aCheck[CHECK_ACTION_RESULT] == CHECK_ACTION_RESULT_ALLOWED;
    }

    function isAllowedSearch ($isPerformAction = false) {
        if ($this->isAdmin()) 
            return true;
        $this->_defineActions();
		$aCheck = checkAction($this->_iProfileId, BX_STORE_SEARCH, $isPerformAction);
        return $aCheck[CHECK_ACTION_RESULT] == CHECK_ACTION_RESULT_ALLOWED;
    }

    function isAllowedAdd ($isPerformAction = false) {
        if ($this->isAdmin()) 
            return true;
        if (!$GLOBALS['logged']['member']) 
            return false;
        $this->_defineActions();
		$aCheck = checkAction($this->_iProfileId, BX_STORE_ADD_PRODUCT, $isPerformAction);
        return $aCheck[CHECK_ACTION_RESULT] == CHECK_ACTION_RESULT_ALLOWED;
    } 

    function isAllowedEdit ($aDataEntry, $isPerformAction = false) {

        // admin and owner can always edit product 
        if ($this->isAdmin() || ($GLOBALS['logged']['member'] && $aDataEntry['author_id'] == $this->_iProfileId && isProfileActive($this->_iProfileId))) 
            return true;

        // check acl
        $this->_defineActions();
		$aCheck = checkAction($this->_iProfileId, BX_STORE_EDIT_ANY_PRODUCT, $isPerformAction);
        return $aCheck[CHECK_ACTION_RESULT] == CHECK_ACTION_RESULT_ALLOWED;
    } 

    function isAllowedMarkAsFeatured ($aDataEntry, $isPerformAction = false) {
        if ($this->isAdmin()) 
            return true;
        $this->_defineActions();
        $aCheck = checkAction($this->_iProfileId, BX_STORE_MARK_AS_FEATURED, $isPerformAction);
        return $aCheck[CHECK_ACTION_RESULT] == CHECK_ACTION_RESULT_ALLOWED;        
    }

    function isAllowedBroadcast ($aDataEntry, $isPerformAction = false) {
        if ($this->isAdmin() || ($GLOBALS['logged']['member'] && $aDataEntry['author_id'] == $this->_iProfileId && isProfileActive($this->_iProfileId))) 
            return true;
        $this->_defineActions();
        $aCheck = checkAction($this->_iProfileId, BX_STORE_BROADCAST_MESSAGE, $isPerformAction);
        return $aCheck[CHECK_ACTION_RESULT] == CHECK_ACTION_RESULT_ALLOWED;        
    }

    function isAllowedDelete (&$aDataEntry, $isPerformAction = false) {
        if ($this->isAdmin() || ($GLOBALS['logged']['member'] && $aDataEntry['author_id'] == $this->_iProfileId && isProfileActive($this->_iProfileId))) 
            return true;
        $this->_defineActions();
		$aCheck = checkAction($this->_iProfileId, BX_STORE_DELETE_ANY_PRODUCT, $isPerformAction);
        return $aCheck[CHECK_ACTION_RESULT] == CHECK_ACTION_RESULT_ALLOWED;
    }     

    function isAllowedShareProduct (&$aDataEntry) {
        return true;
    }

    function isAllowedPurchase(&$aItem) {
        if (!$this->_iProfileId || 0 == $aItem['price'])
            return false;
        return $this->isAdmin() || $this->_oPrivacyFile->check('purchase', $aItem['id'], $this->_iProfileId);
    }

    function isAllowedPostInForum(&$aItem, $iProfileId = -1) {
        if (-1 == $iProfileId)
            $iProfileId = $this->_iProfileId;
        return $this->isAdmin() || ($GLOBALS['logged']['member'] && $aDataEntry['author_id'] == $this->_iProfileId && isProfileActive($this->_iProfileId)) || $this->_oPrivacyProduct->check('post_in_forum', $aItem['id'], $iProfileId);
    }

    function isAllowedDownload(&$aItem) {
        if ($this->isAdmin()) 
            return true;
        if (0 == $aItem['price'] && $this->_oPrivacyFile->check('purchase', $aItem['id'], $this->_iProfileId))
            return true;
        if ($this->_oDb->isPurchasedItem ($this->_iProfileId, $aItem['id'])) 
            return true;
        return false;
    }

    function isAllowedRate(&$aDataEntry) {
        return $this->isAdmin() || $this->isCustomer ($aDataEntry);
    }

    function isAllowedComments(&$aDataEntry) {
        return $this->isAdmin() || $this->isCustomer ($aDataEntry);
    }

    function isAllowedCreatorCommentsDeleteAndEdit (&$aEvent, $isPerformAction = false) {
        if ($this->isAdmin()) return true;
        if (!$GLOBALS['logged']['member'] || $aEvent['ResponsibleID'] != $this->_iProfileId)
            return false;
        $this->_defineActions();
		$aCheck = checkAction($this->_iProfileId, BX_STORE_PRODUCT_COMMENTS_DELETE_AND_EDIT, $isPerformAction);
        return $aCheck[CHECK_ACTION_RESULT] == CHECK_ACTION_RESULT_ALLOWED;
    }

    function isCustomer($aItem) {        
        return $this->_oDb->isCustomer ($this->_iProfileId, $aItem['id']);
    }

    function _defineActions () {
        defineMembershipActions(array('store view product', 'store browse', 'store search', 'store add product', 'store edit any product', 'store delete any product', 'store mark as featured', 'store approve product', 'store broadcast message'));
    }

    // ================================== other function 

    function getGroupName ($mixedId) {
        if ('m' == $mixedId[0]) { 
            require_once(BX_DIRECTORY_PATH_INC . 'membership_levels.inc.php');
            $a = getMembershipInfo (substr($mixedId, 1));
            return $a && isset($a['Name']) ? $a['Name'] : 'undefined';
        } else {
            bx_import('BxDolPrivacyQuery');
            $oPrivacyQuery = new BxDolPrivacyQuery();
            $a = $oPrivacyQuery->getGroupsBy (array('type' => 'id', 'id' => $mixedId));
            return $a && (int)$a['owner_id'] == 0 ? _t('_ps_group_' . $a['id'] . '_title') : $a['title'];
        }
    }

    function _browseMy (&$aProfile) {
        parent::_browseMy ($aProfile, _t('_bx_store_page_title_my_store'));
    }
}

?>
