Files Edit Form Stripping HTML

I am trying to change the files edit form; obtain by pressing the edit action button; to allow HTML in the description.  However, it seems the HTML is removed when the form is submitted.  Can someone explain to me how this is accomplished and perhaps how I can change this so that the HTML is not stripped out?  I assume the form inputs are sent to a function that is cleaning out the HTML code but I am unable to determine which function if this is how it is handled.

Geeks, making the world a better place
Quote · 3 Mar 2013

Let me explain what I am doing here and why I need to allow some HTML in the description box of the "edit" action.  Now as you may be aware, the modules are not independent blocks of code; they utilise other scripts in the site.  It is the same for the files module.  I first started to work with allowing HTML at the time the file was uploaded.  However, that meant going outside of the files module and editing scripts shared with other functions of the site and I immediately ran into problems.  The "edit" action just updates the info of the files section.  Therefore, I decided that members could upload the file and type in the text description and then once the file had been added could then edit the information to include a photo.  Why, do you ask, would someone want to add a photo to the files description?  Simple, because it aids in knowing what the file is about.  Let me cite an example of how someone may be using the files section of Dolphin.

Let's say there are woodworkers on the site and they are sharing woodworking patterns in pdf format.  I upload a pattern of a chest of drawers.  Now I can put in a detail description of the chest of drawers trying to let the other woodworkers get an idea of what type of chest of drawers they will get if they download the pattern; and of course you really don't know until you see it.  Or, I could insert a photo of the completed chest of drawers; something that is usually the case; except on Dolphin where for some strange reason only known to the gods they thought there was only a need for a text description for files.  My members were on me from day one on being able to add a photo to the file description.

 

Note: I have added a special TinyMCE config that will limit what HTML they can add, using the invalid-elements to strip out anything like javascript and iframe but leave text related formatting and the image tag.

Geeks, making the world a better place
Quote · 3 Mar 2013

That will be a little tricky.

The information is saved when one of the two functions are called. One to save the data, the other to update the data. Normally those would be located in the files modules db class. But boonex in their infinite wisdom decided to share a single class among more that one module. So you will find those functions in inc/classes/BxDolFilesDb

The functions are insertData and updateData. Both of those call _setData and that function calls process_db_input with the BX_TAGS_STRIP define passed to it which is what strips out all HTML and PHP tags.

Now you could modify the _setData function to remove the BX_TAGS_STRIP define and replace it with BX_TAGS_NO_ACTION but that will affect all modules that use those functions.

This is the reason i build my own custom modules rather than try to modify dolphin. Chasing their rats nest code is a pain.

To make this a files module only modification the 3 functions, insertData, updateData, and _setData will have to be copied to the modules database class and then the _setData function edited there.

No guarantee this will work. I have not tested it and am not 100% sure i followed their code properly.


https://www.deanbassett.com
Quote · 3 Mar 2013

Ok, try this

Go to inc/classes/BxDolFilesDb.php line _setData function line 182

change this

$sqlQuery .= "`{$this->aFileFields[$sKey]}`='" . process_db_input($sValue, BX_TAGS_STRIP) . "', ";
To this

$sqlQuery .= "`{$this->aFileFields[$sKey]}`='" . process_db_input($sValue, BX_TAGS_VALIDATE) . "', ";
See if this is what you want and you can move this function to photos or any other files module DB class to keep it separate.

so much to do....
Quote · 3 Mar 2013

OK, thanks for the information; I will play with this and report back.

Geeks, making the world a better place
Quote · 3 Mar 2013

I don't knowhow to localise the functions to BxFilesDb.php; perhaps you can explain that to me.  What I did was to go into BxDolFilesDb.php and copied the three functions and then renamed them.  I then changed the function call in BxFilesModule.php to call the renamed function with the BX_TAGS_VALIDATE and it worked as I wanted it to; photo was added.  This will really improve the files module and this is the way it should have been in the first place.  I thought about trying to add a photo block to the files page and then having the upload button for the photo but this really is the easier way to go, including a photo in the description.  Since the uploader is shared as well, I had problems trying to allow a change to the description at the time up the upload and it "hung" the process.

One strange thing, I had the font family and font colour selectors in the TinyMCE config that I created just for the file edit and it would shut the pop-up if I tried to use them.  Inserting an image with the image insert/edit worked fine.

Thanks for the help on this little hack.

Geeks, making the world a better place
Quote · 4 Mar 2013

I wonder if I can add "covers" to sound files as well with this; that is another area that should have had an image that one could associate with the sound file.

Geeks, making the world a better place
Quote · 4 Mar 2013

 

copied the three functions and then renamed them.

You don't rename them. When functions are copied from the parent class to a child class, the ones in the child class are the replacements. BxFilesDb.php is a child of the parent BxDolFilesDb.php

 

 

 

 


https://www.deanbassett.com
Quote · 4 Mar 2013

 

 

copied the three functions and then renamed them.

You don't rename them. When functions are copied from the parent class to a child class, the ones in the child class are the replacements. BxFilesDb.php is a child of the parent BxDolFilesDb.php

That is what I did but it did not work. Which is why I thought I was doing something wrong. Let me try again.

Geeks, making the world a better place
Quote · 4 Mar 2013

It is not using the local copy; it is using BxDolFilesDb.php; do I need to change how I call the function?

if ($this->_oDb->updateData($iFileId, $aValues)) {
                    $sType = $this->_oConfig->getMainPrefix();
                    bx_import('BxDolCategories');
                    $oTag = new BxDolTags();
                    $oTag->reparseObjTags($sType, $iFileId);
                    $oCateg = new BxDolCategories();
                    $oCateg->reparseObjTags($sType, $iFileId);

Geeks, making the world a better place
Quote · 4 Mar 2013

Nope.

I would test on my site, but i don't have time. So just do it the way you did it before.

https://www.deanbassett.com
Quote · 4 Mar 2013

Yes, that got it to working but I want to learn the correct way for this stuff.  Is there some doc I can read on this?

Geeks, making the world a better place
Quote · 4 Mar 2013

Nope. And that should have been the correct way, and it should have worked.

https://www.deanbassett.com
Quote · 4 Mar 2013

You are doing something wrong maybe, it have to work if done right.

paste this in your modules/boonex/files/classes/BxFilesDb.php

function _setData ($aData, $iFileId = 0)
{
     $sqlCond = "";
     $iFileId = (int)$iFileId;
     if ($iFileId > 0) {
         $sqlQuery = "UPDATE";
         $sqlCond = " WHERE `{$this->aFileFields['medID']}`='$iFileId'";
     } else {
         $sqlQuery = "INSERT INTO ";
         // spec key field
         $aData['Hash'] = md5(microtime());
     }
     $sqlQuery .= "`{$this->sFileTable}` SET ";
     foreach ($aData as $sKey => $sValue) {
         if (array_key_exists($sKey, $this->aFileFields))
             $sqlQuery .= "`{$this->aFileFields[$sKey]}`='" . process_db_input($sValue, BX_TAGS_VALIDATE) . "', ";
         }
     return $this->query(trim($sqlQuery, ', ') . $sqlCond);
}

Revert back all your changes and do it on a fresh file.

so much to do....
Quote · 4 Mar 2013

 

I wonder if I can add "covers" to sound files as well with this; that is another area that should have had an image that one could associate with the sound file.

 

Add "Covers" to Sound Files

Make backups of your original files before this modification in case something goes wrong. Then...

 

1) Open the modules/boonex/sounds/classes/BxSoundsUploader.php

     Search and find this code:

function GenSendFileInfoForm($iFileID, $aDefaultValues = array()) {

Add this function before that code line:

            function _GenSendFileInfoForm($iFileID, $aDefaultValues = array(), $aPossibleImage = array(), $aPossibleDuration = array()) {
                header("Content-type: text/html; charset=utf-8");
                $this->addJsTranslation(array(
                    '_bx_' . $this->sUploadTypeLC . 's_val_title_err',
                    '_bx_' . $this->sUploadTypeLC . 's_val_descr_err'
                ));

                $oCategories = new BxDolCategories();
                $oCategories->getTagObjectConfig();
                $aFormCategories['categories'] = $oCategories->getGroupChooser('bx_' . $this->sUploadTypeLC . 's', $this->_iOwnerId, true);
                $aFormCategories['categories']['required'] = false;
                $sKey = 'album';
                $aAlbums = array();
                if ($this->_aExtras[$sKey] != '') {
                    $aAlbums[BX_DOL_UPLOADER_EP_PREFIX . $sKey] = array (
                        'type' => 'hidden',
                        'name' => BX_DOL_UPLOADER_EP_PREFIX . $sKey,
                        'value' => stripslashes($this->_aExtras[$sKey])
                    );

                } else {
                    $oAlbum = new BxDolAlbums('bx_' . $this->sUploadTypeLC . 's');
                    $aAlbumList = $oAlbum->getAlbumList(array('owner'=>$this->_iOwnerId));
           
                    if (count($aAlbumList) > 0) {
                        foreach ($aAlbumList as $aValue)
                            $aList[$aValue['ID']] = stripslashes($aValue['Caption']);
                    }
                    else {
                        $sDefName = $oAlbum->getAlbumDefaultName();
                        $aList[$sDefName] = stripslashes($sDefName);
                    }
                    $aAlbums['album'] = array(
                      'type' => 'select_box',
                      'name' => BX_DOL_UPLOADER_EP_PREFIX . $sKey,
                      'caption' => _t('_sys_album'),
                      'values' => $aList
                    );
                }

                $sCaptionVal = ($this->sSendFileInfoFormCaption != '') ? $this->sSendFileInfoFormCaption : _t('_Info');
                // processing of possible default values
                $aInputValues = array('title', 'tags', 'description', 'type', $this->sUploadTypeLC);
                foreach ($aInputValues as $sField) {
                    $sEmpty = $sField == 'type' ? 'upload' : '';
                    $sTemp = isset($aDefaultValues[$sField]) ? strip_tags($aDefaultValues[$sField]) : $sEmpty;
                    $aDefaultValues[$sField] = $sTemp;
                }
                $aForm = array(
                    'form_attrs' => array(
                        'id' => $this->sUploadTypeLC . '_file_info_form',
                        'method' => 'post',
                        'action' => $this->sWorkingFile,
                        'target' => 'upload_file_info_frame_' . $iFileID,
                        'enctype' => 'multipart/form-data',
                    ),
                    'inputs' => array(
                        'header2' => array(
                            'type' => 'block_header',
                            'caption' => $sCaptionVal,
                            'collapsable' => true
                        ),
                        'title' => array(
                            'type' => 'text',
                            'name' => 'title',
                            'caption' => _t('_Title'),
                            'required' => true,
                            'value' => $aDefaultValues['title']
                        ),
                        'tags' => array(
                            'type' => 'text',
                            'name' => 'tags',
                            'caption' => _t('_Tags'),
                            'info' => _t('_Tags_desc'),
                            'value' => $aDefaultValues['tags']
                        ),
                        'description' => array(
                            'type' => 'textarea',
                            'name' => 'description',
                            'caption' => _t('_Description'),
                            'required' => true,
                            'value' => $aDefaultValues['description']
                        ),
                        'image' => array(
                            'type' => 'file',
                            'name' => 'image',
                            'caption' => _t('_Upload image'),
                        ),
                        'media_id' => array(
                            'type' => 'hidden',
                            'name' => 'file_id',
                            'value' => $iFileID,
                        ),
                        'hidden_action' => array(
                            'type' => 'hidden',
                            'name' => 'action',
                            'value' => 'accept_file_info'
                        ),
                        $this->sUploadTypeLC => array(
                            'type' => 'hidden',
                            'name' => $this->sUploadTypeLC,
                            'value' => $aDefaultValues[$this->sUploadTypeLC]
                        ),
                        'type' => array(
                            'type' => 'hidden',
                            'name' => 'type',
                            'value' => $aDefaultValues['type']
                        )
                    ),
                );

                //--- Process Extras ---//
                foreach($this->_aExtras as $sKey => $mixedValue)
                    $aForm['inputs'][BX_DOL_UPLOADER_EP_PREFIX . $sKey] = array (
                        'type' => 'hidden',
                        'name' => BX_DOL_UPLOADER_EP_PREFIX . $sKey,
                        'value' => $mixedValue
                    );

                // merging categories
                $aForm['inputs'] = $this->getUploadFormArray($aForm['inputs'], array($aFormCategories, $aAlbums));

                if (is_array($aPossibleImage) && count($aPossibleImage)>0)
                    $aForm['inputs'] = array_merge($aForm['inputs'], $aPossibleImage);

                if (is_array($aPossibleDuration) && count($aPossibleDuration)>0)
                    $aForm['inputs'] = array_merge($aForm['inputs'], $aPossibleDuration);

                $aForm['inputs'][] = array(
                    'type' => 'input_set',
                    'colspan' => true,
                    0 => array(
                        'type' => 'submit',
                        'name' => 'upload',
                        'value' => _t('_Submit'),
                        'colspan' => true,
                        'attrs' => array(
                            'onclick' => "return parent." . $this->_sJsPostObject . ".doValidateFileInfo(this, '" . $iFileID . "');",
                        )
                    ),
                    1 => array(
                        'type' => 'button',
                        'name' => 'close',
                        'value' => _t('_bx_'.$this->sUploadTypeLC.'s_close'),
                        'colspan' => true,
                        'attrs' => array(
                            'onclick' => "return parent." . $this->_sJsPostObject . ".cancelSendFileInfo('" . $iFileID . "', ''); ",
                        )
                    ),
                    2 => array(
                        'type' => 'button',
                        'name' => 'delete',
                        'value' => _t('_bx_'.$this->sUploadTypeLC.'s_admin_delete'),
                        'colspan' => true,
                        'attrs' => array(
                            'onclick' => "return parent." . $this->_sJsPostObject . ".cancelSendFileInfo('" . $iFileID . "', '" . $this->sWorkingFile . "'); ",
                        )
                    )
                );

                $oForm = new BxTemplFormView($aForm);
                $sForm = $oForm->getCode();
                $sFormSafeJS = str_replace(array("'", "r", "n"), array("'"), $sForm);

                return "<script src='" . BX_DOL_URL_ROOT . "inc/js/jquery.webForms.js' type='text/javascript' language='javascript'></script><script type='text/javascript'>parent." . $this->_sJsPostObject . ".genSendFileInfoForm('" . $iFileID . "', '" . $sFormSafeJS . "'); parent." . $this->_sJsPostObject . "._loading(false);</script>";
            }

In the same file, find this code:

$oCateg->reparseObjTags('bx_sounds', $iMusicID);

And add this code below it:

            if( isset($_FILES['image']['type']) ) {
                $this -> oModule -> uploadSoundThumb($_FILES['image'], $iMusicID);
            }

2. Open the modules/boonex/sounds/classes/BxSoundsConfig.php

Search and find this code:

            $this->aFilePostfix = array(
                '.mp3',
                '.jpg'
            );

Add this code below it:

            $this -> iSoundThumbWidth  = 148;
            $this -> iSoundThumbHeight = 110;
            $this -> aAllowedFileType  = array('image/jpeg', 'image/png', 'image/gif', 'image/jpg');
            $this -> sThumbSaveDir     = BX_DIRECTORY_PATH_ROOT . 'flash/modules/mp3/files/';
            $this -> sThumbUrl         = BX_DOL_URL_ROOT . 'flash/modules/mp3/files/';

3. Open the modules/boonex/sounds/classes/BxSoundsModule.php

Search and find this code:

            function serviceGetProfileCat () {
                return PROFILE_SOUND_CATEGORY;
            }

Add this code below that:


            function actionEdit ($iFileId) {
                $iFileId = (int)$iFileId > 0 ? (int)$iFileId : (int)$_POST['fileId'];
                if ($iFileId == 0)
                   exit;
               
                $this->aPageTmpl['name_index'] = 44;
                $sJsCode = '<script language="javascript">window.setTimeout(function () { window.parent.opener.location = window.parent.opener.location; window.parent.close(); }, 3000); </script>';
                $aManageArray = array('medTitle', 'medTags', 'medDesc', 'medProfId', 'Categories');
                $aInfo = $this->_oDb->getFileInfo(array('fileId'=>$iFileId), false, $aManageArray);
                if (!$this->isAllowedEdit($aInfo))
                   $sCode = MsgBox(_t('_' . $this->_oConfig->getMainPrefix() . '_access_denied')) . $sJsCode;
                else {
                    $oCategories = new BxDolCategories();
                    $oCategories->getTagObjectConfig();               
                    $aCategories = $oCategories->getGroupChooser($this->_oConfig->getMainPrefix(), $this->_iProfileId, true);
                    $aCategories['value'] = explode(CATEGORIES_DIVIDER, $aInfo['Categories']);
                   
                    $sThumbImage = $this -> _oConfig -> sThumbSaveDir . $iFileId . '.jpg';

                    $aForm = array(
                        'form_attrs' => array(
                            'id' => $this->_oConfig->getMainPrefix() . '_upload_form',
                            'method' => 'post',
                            'action' => BX_DOL_URL_ROOT . $this->_oConfig->getBaseUri() . 'edit/' . $iFileId,
                            'enctype' => 'multipart/form-data',
                        ),
                        'params' => array (
                            'db' => array(
                                'submit_name' => 'submit',
                            ),
                            'checker_helper' => 'BxSupportCheckerHelper',
                        ),
                        'inputs' => array(
                            'header' => array(
                                'type' => 'block_header',
                                'caption' => _t('_Info'),
                            ),
                            'title' => array(
                                'type' => 'text',
                                'name' => 'medTitle',
                                'caption' => _t('_Title'),
                                'required' => true,
                                'value' => $aInfo['medTitle'],
                                'checker' => array ( 
                                    'func' => 'length',
                                    'params' => array(3, 128),
                                    'error' => _t('_td_err_incorrect_length'),
                                ),
                            ),
                            'tags' => array(
                                'type' => 'text',
                                'name' => 'medTags',
                                'caption' => _t('_Tags'),
                                'info' => _t('_Tags_desc'),
                                'value' => $aInfo['medTags']
                            ),
                            'description' => array(
                                'type' => 'textarea',
                                'name' => 'medDesc',
                                'caption' => _t('_Description'),
                                'required' => true,
                                'value' => $aInfo['medDesc'],
                                'checker' => array ( 
                                    'func' => 'length',
                                    'params' => array(3, 65536),
                                    'error' => _t('_td_err_incorrect_length'),
                                ),
                            ),
                            'image' => array(
                                'type' => 'file',
                                'name' => 'image',
                                'caption' => _t('_Upload image'),
                            ),
                            'current_image' => array(
                                'type' => 'custom',
                                'content' => _t('_Delete') . ' <input name="delete_thumb" type="checkbox"><br /><img src="'
                                    . $this -> _oConfig -> sThumbUrl . $iFileId . '.jpg" />',
                            ),
                            'categories' => $aCategories,
                            'fileId' => array(
                                'type' => 'hidden',
                                'name' => 'fileId',
                                'value' => $iFileId,
                            ),
                            'medProfId' => array(
                                'type' => 'hidden',
                                'name' => 'medProfId',
                                'value' => $aInfo['medProfId'],
                            ),
                            'submit' => array(
                                'type' => 'submit',
                                'name' => 'submit',
                                'value' => _t('_Submit'),
                                'colspan' => true,
                            ),
                        ),
                    );
                   
                    $bThumbExist = file_exists($sThumbImage) ? true : false;
                    if(!$bThumbExist) {
                        unset($aForm['inputs']['current_image']);
                    }

                    $oForm = new BxTemplFormView($aForm);
                    $oForm->initChecker();           
                    if ($oForm->isSubmittedAndValid()) {

                        $aValues = array();
                        foreach ($aManageArray as $sKey) {
                            if ($sKey != 'Categories')
                               $aValues[$sKey] = $_POST[$sKey];
                            else {
                               $aValues[$sKey] = implode(CATEGORIES_DIVIDER, $_POST[$sKey]);
                            }
                        }

                        $bUploadRes = false;

                        if( isset($_POST['delete_thumb']) && $bThumbExist ) {
                            //delete thumb
                            @unlink($sThumbImage);
                            $bUploadRes = true;
                        }

                        if( isset($_FILES['image']['type']) ) {
                            $this -> uploadSoundThumb($_FILES['image'], $iFileId);
                            $bUploadRes = true;
                        }

                        if ($this->_oDb->updateData($iFileId, $aValues) || $bUploadRes) {
                            $sType = $this->_oConfig->getMainPrefix();
                            bx_import('BxDolCategories');
                           
                            $oTag = new BxDolTags();
                            $oTag->reparseObjTags($sType, $iFileId);
                            $oCateg = new BxDolCategories();
                            $oCateg->reparseObjTags($sType, $iFileId);

                            $sCode = MsgBox(_t('_' . $this->_oConfig->getMainPrefix() . '_save_success')) . $sJsCode;
                        }
                    }   
                    else {
                        $sCode = $oForm->getCode();              
                        $this->aPageTmpl['css_name'] = array('forms_adv.css', 'explanation.css');
                    }   
                }   
                $this->aPageTmpl['header'] = _t('_Edit');
                $this->_oTemplate->pageCode($this->aPageTmpl, array('page_main_code' => $sCode));            
            }

            function uploadSoundThumb($aThumbInfo, $iFileId)
            {
                if( isset($aThumbInfo['type'], $aThumbInfo['tmp_name'])
                    && in_array($aThumbInfo['type'], $this -> _oConfig -> aAllowedFileType) ) {

                    //upload and resize thumb image
                    return imageResize($aThumbInfo['tmp_name']
                        , $this -> _oConfig -> sThumbSaveDir . $iFileId . '.jpg'
                        , $this -> _oConfig -> iSoundThumbWidth
                        , $this -> _oConfig -> iSoundThumbHeight);
                }
            }

4. Open the flash/modules/mp3/inc/actions.inc.php

Search and remove these lines of code:

           case 'screenshot':
            //--- Prepare data ---//
            $iWidth = isset($_REQUEST['width']) ? (int)$_REQUEST['width'] : 0;
            $iHeight = isset($_REQUEST['height']) ? (int)$_REQUEST['height'] : 0;
            $sData = isset($_REQUEST['data']) ? process_db_input($_REQUEST['data']) : "";
            $aImageData = explode(',', $sData);
            $iLength = count($aImageData);
            for($i=0; $i<$iLength; $i++)
                $aImageData[$i] = base_convert($aImageData[$i], 36, 10);
            if($iLength != $iWidth * $iHeight || !function_exists("imagecreatetruecolor")) break;

            //--- Create Image Resource ---//
            $rImage = @imagecreatetruecolor($iWidth, $iHeight);
            for ($i = 0, $y = 0; $y < $iHeight; $y++ )
                for ( $x = 0; $x < $iWidth; $x++, $i++)
                    @imagesetpixel ($rImage, $x, $y, $aImageData[$i]);

            //--- Save image file ---//
            $sUser = process_db_input($_REQUEST['user']);
            if(empty($sId)) $sId = $sUser . TEMP_FILE_NAME;
            $sFileName = $sFilesPathMp3 . $sId . SCREENSHOT_EXT;
            @imagejpeg($rImage, $sFileName, 100);
            break;

This hack was posted by Esase, just reposting it. Seems to work as far as I can tell.

http://ModMyCMS.com --> Dolphin Hacks &Mods
Quote · 4 Mar 2013

OK, thanks everyone.  Will give it a go when I have the time; having to work away from home today.

Geeks, making the world a better place
Quote · 4 Mar 2013

 

You are doing something wrong maybe, it have to work if done right.

paste this in your modules/boonex/files/classes/BxFilesDb.php

function _setData ($aData, $iFileId = 0)
{
     $sqlCond = "";
     $iFileId = (int)$iFileId;
     if ($iFileId > 0) {
         $sqlQuery = "UPDATE";
         $sqlCond = " WHERE `{$this->aFileFields['medID']}`='$iFileId'";
     } else {
         $sqlQuery = "INSERT INTO ";
         // spec key field
         $aData['Hash'] = md5(microtime());
     }
     $sqlQuery .= "`{$this->sFileTable}` SET ";
     foreach ($aData as $sKey => $sValue) {
         if (array_key_exists($sKey, $this->aFileFields))
             $sqlQuery .= "`{$this->aFileFields[$sKey]}`='" . process_db_input($sValue, BX_TAGS_VALIDATE) . "', ";
         }
     return $this->query(trim($sqlQuery, ', ') . $sqlCond);
}

Revert back all your changes and do it on a fresh file.

Thanks but no, it still does not use the local function in BxFilesDb.

Geeks, making the world a better place
Quote · 5 Mar 2013

 Ok it hurts but good we tried. Something else might be wrong here. Cry

Well it worked somehow so lets move on.

Thanks but no, it still does not use the local function in BxFilesDb.

 

so much to do....
Quote · 5 Mar 2013

OK, this is working now.  The problem is that I am an idiot.  I had the changed function outside of the class; class BxFilesDb extends BxDolFilesDb{}.  No wonder it did not use it instead of the function in BxDolFilesDb.

Thanks everyone for your help.

Geeks, making the world a better place
Quote · 5 Mar 2013
 
 
Below is the legacy version of the Boonex site, maintained for Dolphin.Pro 7.x support.
The new Dolphin solution is powered by UNA Community Management System.