Custom field plugin, multiple fields within the same custom field

Started by Kuubs, November 22, 2023, 14:30:01 PM

Previous topic - Next topic

Kuubs

Hello,

I was wondering if it's possible to create a new custom field type to show multiple text editors so I can save data in a way I need to save it.. The documentation regarding this kind of plugin is very scarce, can anyone point me in the right direction?

So instead of an "editor" custom field i need a custom field that shows 2 or 3 editors, multiple fields within the same custom field

Ok I got this code:


<?php
defined
('_JEXEC') or die('Restricted access');

if (!
class_exists('vmCustomPlugin')) {
    require(
VMPATH_PLUGINLIBS DS 'vmcustomplugin.php');
}

class 
plgVmCustomSpecificaties extends vmCustomPlugin {

    function 
__construct(&$subject$config) {
        
parent::__construct($subject$config);

        
$this->_tablepkey 'id';
        
$this->tableFields array_keys($this->getTableSQLFields());
        
$this->varsToPush = array(
            
'icon_field' => array('''string'),
            
'text_field' => array('''string'),
            
'html_field1' => array('''string'),
            
'html_field2' => array('''string')
        );

        
$this->setConfigParameterable($this->_configTableFieldName$this->varsToPush);
    }

    function 
getTableSQLFields() {
        
$SQLfields = array(
            
'id' => 'int(11) UNSIGNED NOT NULL AUTO_INCREMENT',
            
'virtuemart_product_id' => 'int(11) UNSIGNED',
            
'icon_field' => 'TEXT'// Normal text field
            
'text_field' => 'TEXT'// Normal text field
            
'html_field1' => 'MEDIUMTEXT'// First HTML editor field
            
'html_field2' => 'MEDIUMTEXT' // Second HTML editor field
        
);

        return 
$SQLfields;
    }

    function 
plgVmOnProductEdit($field$productId, &$row, &$retValue) {
        if (
$field->custom_element != $this->_name) return '';
    
        
$html ''// Initialize HTML variable
    
        // Icon field
        
$html .= '<div>Icon Field:</div>';
        
$html .= '<textarea name="field['.$row.']['.$this->_name.'][icon_field]" style="width: 100%; height: 100px;">';
        
$html .= htmlspecialchars($field->icon_field);
        
$html .= '</textarea><br/>';
    
        
// Text field
        
$html .= '<div>Text Field:</div>';
        
$html .= '<textarea name="field['.$row.']['.$this->_name.'][text_field]" style="width: 100%; height: 100px;">';
        
$html .= htmlspecialchars($field->text_field);
        
$html .= '</textarea><br/>';
    
        
// First HTML editor field
        
$editor JFactory::getEditor();
        
$html .= '<div>HTML Field 1:</div>';
        
$html .= $editor->display('field['.$row.']['.$this->_name.'][html_field1]'htmlspecialchars($field->html_field1), '100%''200''75''20'false);
    
        
// Second HTML editor field
        
$html .= '<div>HTML Field 2:</div>';
        
$html .= $editor->display('field['.$row.']['.$this->_name.'][html_field2]'htmlspecialchars($field->html_field2), '100%''200''75''20'false);
    
        
$retValue .= $html;
        
$row++;
        return 
true;
    }
    

    
// Additional functions as per your requirement:

    
function plgVmOnDisplayProductFE(&$product, &$group) {
        if (
$group->custom_element != $this->_name) return '';

        
$this->_tableChecked true;
        
$this->getCustomParams($group);
        
$this->getPluginCustomData($group$product->virtuemart_product_id);

        
// Modify this to display your custom fields on the front end
        
$group->display .= $this->renderByLayout('default', array($this->params, &$group));

        return 
true;
    }

    function 
plgVmOnStoreProduct($data$plugin_param$old_customfield_ids$key = -1) {
        return 
$this->OnStoreProduct($data$plugin_param$old_customfield_ids$key);
    }

    public function 
plgVmOnStoreInstallPluginTable($plgType$data$table) {
        if (
$plgType != $this->_psType) {
            return 
false;
        }
        if (!empty(
$data['custom_element']) and $data['custom_element'] != $this->_name) {
            return 
false;
        }

        return 
$this->onStoreInstallPluginTable($plgType$data['custom_element']);
    }

    function 
plgVmSetOnTablePluginParamsCustom($name$id, &$table) {
        return 
$this->setOnTablePluginParams($name$id$table);
    }

    function 
plgVmDeclarePluginParamsCustomVM3(&$data) {
        return 
$this->declarePluginParams('custom'$data);
    }

    
// Continue with other functions as needed...
}

// No closing PHP tag to prevent accidental output



it sows the fields, but it's not saving.. Any idea why??

Studio 42

You can buy a plugin that include certainly what you need https://shop.st42.fr/en/products/shortcodes.htm
https://shop.st42.fr/en/shorcodes-english-doc#url for eg have a link, a HTML description, 2 icons and a class field

Kuubs

Quote from: Studio 42 on November 25, 2023, 11:21:19 AM
You can buy a plugin that include certainly what you need https://shop.st42.fr/en/products/shortcodes.htm
https://shop.st42.fr/en/shorcodes-english-doc#url for eg have a link, a HTML description, 2 icons and a class field
That looks great, and i can do that all in 1 custom field?

But looking at my code do you see why it does not save?

Studio 42

i use json encode/decode to save the values
You have plenty missing code to do it work

Kuubs

Quote from: Studio 42 on November 26, 2023, 19:37:25 PM
i use json encode/decode to save the values
You have plenty missing code to do it work

Well can you give me pointers? Am i using the correct method? etc?

And can you answer the question whether or not your plugin can add 1 custom field with 4 different like this:

https://i.imgur.com/sPSUmEQ.png

Or can you give me the documentation where i can find the correct methods to use?

balai

Why not using a group custom field that includes you individual editors?

Kuubs

Quote from: balai on November 27, 2023, 15:04:21 PM
Why not using a group custom field that includes you individual editors?
Because that is not what i am looking for. I need an array with different values within the same tag. For easy order management.

- Specifications
-- Icon
-- Title
-- Content 1
-- Content 2

It's getting really messy when I am not grouping these fields in a single custom field.

But I am seriously weirded out by the people just refusing to answer my question... Aren't we here to help eachother"? Because the documentation of Virtuemart is really lacking hard. Where can I see what methods I need to use?? There aren't any examples or anything. Really annoying to be honest.

Studio 42

@kuubs
I explained you what to do(json encode/decode)
If you do not understand what i mean then you have to check some PHP tutorial. I'm not here to teach you PHP
Customfields only save a json or a simple value
customfield_params can use JSON
table fields are :
customfield_value
customfield_params

Kuubs

Quote from: Studio 42 on November 27, 2023, 20:18:37 PM
@kuubs
I explained you what to do(json encode/decode)
If you do not understand what i mean then you have to check some PHP tutorial. I'm not here to teach you PHP
Customfields only save a json or a simple value
customfield_params can use JSON
table fields are :
customfield_value
customfield_params

I'm not sure if you understand what I ask. I know about encoding and decoding, but that is not my question. The data is not being saved at all, because the correct method is not being triggered. It's about what method I have to use to trigger the onSaveProduct.

Kuubs

Max helped me in writing and optimizing the code. This is the working code:



<?php
defined
('_JEXEC') or die('Restricted access');


class 
plgVmCustomSpecificaties extends vmCustomPlugin {

    function 
__construct(&$subject$config) {
        
parent::__construct($subject$config);

        
$this->_tablepkey 'id';
       
    $varsToPush = array(
            
'icon_field' => array('''string'),
            
'text_field' => array('''string'),
            
'html_field1' => array('''string'),
            
'html_field2' => array('''string')
        );

        
$this->setConfigParameterable('customfield_params'$varsToPush);
    }


    function 
plgVmOnProductEdit($field$productId, &$row, &$retValue) {
        if (
$field->custom_element != $this->_name) return '';
        
$html ''// Initialize HTML variable
    
        // Icon field
        
$html .= '<div>Icon Field:</div>';
        
$html .= '<textarea name="customfield_params['.$row.'][icon_field]" style="width: 100%; height: 100px;">';
        
$html .= htmlspecialchars($field->icon_field);
        
$html .= '</textarea><br/>';
    
        
// Text field
        
$html .= '<div>Text Field:</div>';
        
$html .= '<textarea name="customfield_params['.$row.'][text_field]" style="width: 100%; height: 100px;">';
        
$html .= htmlspecialchars($field->text_field);
        
$html .= '</textarea><br/>';
    
        
// First HTML editor field
        
$editor JFactory::getEditor();
        
$html .= '<div>HTML Field 1:</div>';
        
$html .= $editor->display('customfield_params['.$row.'][html_field1]'htmlspecialchars($field->html_field1), '100%''200''75''20'false);
    
        
// Second HTML editor field
        
$html .= '<div>HTML Field 2:</div>';
        
$html .= $editor->display('customfield_params['.$row.'][html_field2]'htmlspecialchars($field->html_field2), '100%''200''75''20'false);
    
        
$retValue .= $html;
        
$row++;
        return 
true;
    }
    

    
// Additional functions as per your requirement:

function plgVmOnDisplayProductFEVM3(&$product,&$group) {

if ($group->custom_element != $this->_name) return '';
$group->display .= $this->renderByLayout('default',array(&$product,&$group) );
return true;
}

function plgVmOnViewCartVM3(&$product, &$productCustom, &$html) {
if (empty($productCustom->custom_element) or $productCustom->custom_element != $this->_name) return false;

if(empty($product->customProductData[$productCustom->virtuemart_custom_id][$productCustom->virtuemart_customfield_id])) return false;
foreach( $product->customProductData[$productCustom->virtuemart_custom_id] as $k =>$item ) {
if($productCustom->virtuemart_customfield_id == $k) {
if(isset($item['comment'])){
$html .='<span>'.vmText::_($productCustom->custom_title).' '.$item['comment'].'</span>';
}
}
}
return true;
}

function plgVmOnViewCartModuleVM3( &$product, &$productCustom, &$html) {
return $this->plgVmOnViewCartVM3($product,$productCustom,$html);
}

function plgVmDisplayInOrderBEVM3( &$product, &$productCustom, &$html) {
$this->plgVmOnViewCartVM3($product,$productCustom,$html);
}

function plgVmDisplayInOrderFEVM3( &$product, &$productCustom, &$html) {
$this->plgVmOnViewCartVM3($product,$productCustom,$html);
}


/**
 *
 * vendor order display BE
 */
function plgVmDisplayInOrderBE(&$item$productCustom, &$html) {
if(!empty($productCustom)){
$item->productCustom $productCustom;
}
if (empty($item->productCustom->custom_element) or $item->productCustom->custom_element != $this->_name) return '';
$this->plgVmOnViewCart($item,$productCustom,$html); //same render as cart
}


/**
 *
 * shopper order display FE
 */
function plgVmDisplayInOrderFE(&$item$productCustom, &$html) {
if(!empty($productCustom)){
$item->productCustom $productCustom;
}
if (empty($item->productCustom->custom_element) or $item->productCustom->custom_element != $this->_name) return '';
$this->plgVmOnViewCart($item,$productCustom,$html); //same render as cart
}

function plgVmDeclarePluginParamsCustomVM3(&$data){
return $this->declarePluginParams('custom'$data);
}

function plgVmGetTablePluginParams($psType$name$id, &$xParams, &$varsToPush){
return $this->getTablePluginParams($psType$name$id$xParams$varsToPush);
}

function plgVmSetOnTablePluginParamsCustom($name$id, &$table,$xParams){
return $this->setOnTablePluginParams($name$id$table,$xParams);
}



    
// Continue with other functions as needed...
}

// No closing PHP tag to prevent accidental output


No need to make new tables or anything. This will use the native custom field VM code

Studio 42

I said you to use customfield_params
VM do not filter what you save in the customfield_params
So i do not use native code in my case