Twitter
Sun
04
May
'08
PDF
Print
Send
 
Hits (5328) | Comments (10) | Favorited (5) | Votes (0)

This is great news and possibility to create any field type you want on plugin base. And that is very simple.

First let's see an installation XML file.

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <install version="1.5" type="plugin" group="joomsuite_content_fields">
  3. <name>Content Field - Text</name>
  4. <author>JoomSuite</author>
  5. <creationDate>May 2008</creationDate>
  6. <copyright>Copyright (C) 2005 - 2008 JoomSuite. All rights reserved.</copyright>
  7. <license>Commercial</license>
  8. <authorEmail>support@mightyextensions.com</authorEmail>
  9. <authorUrl>www.mightyextensions.com</authorUrl>
  10. <version>1.0</version>
  11. <description>
  12. Plugin for Resources component add new field type (Text)
  13. </description>
  14. <files>
  15. <filename plugin="text">text.php</filename>
  16. </files>
  17. <params>
  18. <param name="short" type="radio" default="0" label="Simple Mode on frontend"
  19. description="Show only general toolbar butons with editor">
  20. <option value="0">No</option>
  21. <option value="1">Yes</option>
  22. </param>
  23. </params>
  24. </install>

Please, pay attantion on group name in line 2 also on plugin name in line 13.
This name will be considered as name of new field type. You can add any parameters
you want and late you can use it to create more flexible and addoptive field types.

The Plugin system have 3 main events triggered.

onRenderField

This event is triggered on creating fields on article create/edit form.

  1. function onRenderField( &amp;$obj, &amp;$params, $type)
  2. {
  3. if($type != 'text') return;
  4. ?>
  5. <input type="text" style="width:<?php echo $params->get('field_size')?>"
  6. name="fields[<?php echo $obj->id?>]"
  7. value="<?php echo stripslashes($obj->field_value) ?>"/>
  8. <?php
  9. }

This event do not return anything but echo HTML directly. Please, pay attention on line 3.
This line should be first in every event you only need to change 'html' to plugin name you
set in installation XML on line 13.This event receive 3 parameters.

  • $obj - Is an object that contain field information. To create this object this query was used
       SELECT f.*, v.`field_value` 
         FROM `jos_js_res_fields` AS f 
    LEFT JOIN `jos_js_res_record_values` AS v ON v.`field_id` = f.`id`
        WHERE f.`published` = 1;
     

    So to find out what properties this object have look that table.
    But I believe that you will need only 'id' and 'field_value'

  • $params - is a field params that user set on field creation (not on plugin editing)
  • $type - name of the plugin actually

Also not that to get $value of this field to next event automatically you need
to name field as in line 6 (fields[$obj->id]).
Example:
 

echo "<input type='text' name='fields[" . $obj->id . "]'>";

In any case if you create your own name it is smart idea to use ID of the field in the
name to make it unique and you will need to get value using JRequest as it will not be passed to event.

Line 5 set size to field. Size is the global parameter for field. $params->get('field_size')
return value even if you not created this parameter for plugin. Do not forget to use it.

By the way as one of the idea, you can change field views on front-end
and back-end using $mainframe->isAdmin().

onBeforeSave

This event is triggered before storing field value to DB. In this event you can
get$value of your field or set of fields, and prepare it to store in DB.

function onBeforeSave(&amp;$value, &amp;$params, $type, $id, $row, &amp;$error)
{
    if($type != 'html') return;
    if(!$value) return;
    $db = JFactory::getDBO();
 
    $text = stripslashes($value);
    $value = $db->getEscaped(str_replace( '<br>', '<br />', $text ));
} 
 

This function receive 6 parameters.

  • $value - Is an value of the field. Value may not be passed as content not sure
    how you named your field but everything you set to this parameter will be stored
    as field value. Value will be passed only if you named your field as recommended
    in onRenderField event description. Other case you may need to use JRequest
    to get initial field value.
  • $params - is a field params that user set on field creation (not on plugin editing)
  • $type - name of the plugin actually
  • $id - ID of the field. Usually used to identify or get value of other fields that
    was named using $id to make name unique.
  • $row - is an object of just saved record. You can use $row->id or $row->user_id
    to create folder to store file or make other actions.
  • $error - is a trigger for producing error. If you check value and it is not correctly
    formatted you may do like this
    if(!in_array($ext, $exts))
    {
        $msg = JText::_("File is not apropriate format");
        $msg .= "<br>File: ".$name;
        $msg .= "<br>Allowed Formats: ".implode(", ", $exts);
        JError::raiseWarning(403, $msg);
        $error = 1; return;
    }
     

    This example check if extension of uploaded file is correct and display
    error and open form for correcting entered information.

Note everything you set to $value variable will be stored to DB. You do not need to return anything.
 

By the way, best way to store arrays is to path it through serialize() function.

onRenderFieldValue

And this is most simple event, that render field on frontend in article view.

function onRenderFieldValue(&amp;$out, &amp;$field, &amp;$params, $type)
{
    if(!$field->field_value) return;
    if($type != 'select') return;
 
    $val = explode("^", $field->field_value);
 
    if(@$val[1]) $color = ' style="color:'.@$val[1].'" '; else $color = '';
 
    $out = "<span{$color}>{$val[0]}</span>";
}

This function receive 4 parameters.

  • $out - This is variable you should set complete HTML text that you
    want to be displayed.
  • $field - This is object contain field information. I think that only useful here is
    $field->field_value that contain value you saved in previous event.
  • $params - This is a field params that user set on field creation (not on plugin editing)
  • $type - This is the name of the plugin actually

So everything you set to $out variable will be rendered as field value.
You do not need to return anything.

Construction
 

And finaly constration notes and full plugin example.

<?php
defined( '_JEXEC' ) or die( 'Restricted access' );
 
jimport( 'joomla.plugin.plugin' );
 
class plgJoomsuite_content_fieldsText extends JPlugin
{
    function plgJoomsuite_content_fieldsText( &amp;$subject, $params )
    {
        parent::__construct( $subject, $params );
    }
 
    function onRenderField( &amp;$obj, &amp;$params, $type)
    {
        if($type != 'text') return;
        ?>
            <input type="text"  style="width:<?php echo $params->get('field_size')?>" 
                name="fields[<?php echo $obj->id?>]" 
                value="<?php echo stripslashes($obj->field_value) ?>"/>
        <?php
    }
 
    function onBeforeSave(&amp;$value, &amp;$params, $type, $id, $row, &amp;$error)
    {
        if($type != 'text') return;
        if(!$value) return;
 
        $db = &amp;JFactory::getDBO();
        $value = $db->getEscaped(trim($value));
    }
 
    function onRenderFieldValue(&amp;$out, &amp;$field, &amp;$params, $type)
    {
        if($type != 'text') return;
        if(!$field->field_value) return;
 
        $out = $field->field_value;    
    }
} 
?>

Above is most simple text type plugin. Please, note plugin name
plgJoomsuite_content_fieldsText. It is constructed of 3 parts
plg - Joomsuite_content_fields - Text which actually prefix - group name - plugin name.
Also function with the same name should be created for proper class construction on plugin call.

I hope you now can see endless posibilities and options that you can create for JoomSuite Content.


Comments
tomstgeorgeAvatar
Quote
- -
Written by tomstgeorge on 05 June 2008

Line 13 of the xml files refers to 'html' and 'html.php'

But the rest of the article talks about a field called 'text' 

-
grzegorz21Avatar
Quote
- -
Written by grzegorz21 on 19 March 2009

ble

-
avatar
Quote
- -
Written by Shady on 21 March 2009

I am having a good knowledge base of Joomla, but this tutorial makes me confusion

 Would you please explain more simply so we can make our custom types easily.

-
solutionsExpertAvatar
Quote
- -
Written by solutionsExpert VIP on 24 October 2009

was this written to make it hard to do this? lol

it needs to flow better a better example maybe? i would help with english translations after you think its ready...

using just translators doensn't help for things like this

-
solutionsExpertAvatar
Quote
- -
Written by solutionsExpert VIP on 24 October 2009

full example from package for text...october 24 09

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

jimport( 'joomla.plugin.plugin' );

class plgJoomsuite_content_fieldsText extends JPlugin
{
    function plgJoomsuite_content_fieldsText( &$subject, $params )
    {
        parent::__construct( $subject, $params );
    }

    function onRenderField( &$obj, &$params, $type)
    {
        if($type != 'text') return;
        $unique_name =  $obj->id;
        $def = JRequest::getVar('fields', null, 'default', 'array');
        if( $def[$obj->id] ) $obj->field_value = $def[$obj->id];

        $pregmatch = $params->get('pregmatch', 0);

        switch( $pregmatch ){
            // only numbers
            case 'num' :
                ?>
<SCRIPT type="text/javascript">
                function pregmatch_<?php echo $unique_name ?>()
                {
                    var currField = document.getElementById( 'fields<?php echo $obj->id; ?>').value;
                    var regExp =  /[^0-9]+/;
                    currField = currField.replace( regExp, '');                    
                    document.getElementById('fields<?php echo $obj->id ?>').value = currField;                              
                }                                    
            </SCRIPT>
                <?php
                break;
case 'text':
    ?>
<SCRIPT type="text/javascript">
                function pregmatch_<?php echo $unique_name ?>()
                {
                    var currField = document.getElementById( 'fields<?php echo $obj->id; ?>').value;
                    var regExp =  /[^a-zA-Z\W!\@_]+/;
                    currField = currField.replace( regExp, '');                    
                    document.getElementById('fields<?php echo $obj->id ?>').value = currField;                              
                }                                    
            </SCRIPT>
    <?php
    break;
case 'float':
    ?>
<SCRIPT type="text/javascript">
                function pregmatch_<?php echo $unique_name ?>()
                {
                    var currField = document.getElementById( 'fields<?php echo $obj->id; ?>').value;
                    var reg1 = /[^0-9]+/;                    
                    var arrayTokens = currField.split( '.', 2 );                    
                    
                    var part1 = '';                                        
                    if( arrayTokens[ 0 ] ){
                        part1 = arrayTokens[ 0 ];
                        part1 = part1.replace(reg1, '');
                    }
                                        
                    var part2 = '';
                    if( arrayTokens[ 1 ] ){                
                        part2 = arrayTokens[ 1 ];
                        part2 = part2.replace(reg1, '');
                    }                    
                    
                    var result = '';
                    if( arrayTokens[ 0 ] && arrayTokens[ 1 ] )
                        result = part1 + '.' + part2;                    
                    else if( arrayTokens[0] && !arrayTokens[ 1 ]){
                        result = part1;
                        if( currField.charAt( currField.length - 1 ) == '.' )
                            result += '.';
                    }else if( arrayTokens[1] ){
                        result = part2;
                    }
                    
                    document.getElementById('fields<?php echo $obj->id; ?>').value = result;                                                            
                }
            </SCRIPT>
    <?php
    break;
case 'custom':
    $out = $params->get('custom_cs');
    ?>
<SCRIPT type="text/javascript">
                function pregmatch_<?php echo $unique_name ?>()
                {                
                    <?php
                        $pattern  = "/\[id\]/i";
                        $out = preg_replace($pattern, $obj->id, $out);
                        echo $out;                
                    ?>
                }
            </SCRIPT>
                    <?php
                    break;
case '0': break;
default:
    ?>
<SCRIPT type="text/javascript">    function pregmatch_<?php echo $unique_name ?>(){} </SCRIPT>
    <?php
    break;
}
        echo "<span>".$params->get('sign_before')."</span>";
        if ($pregmatch)
        $pregmatch = "onkeyup='pregmatch_$unique_name()'";
        ?>            
            <input type="text" <?php echo $pregmatch ?> id="fields<?php echo $obj->id?>" <?php echo ((int)$params->get('maxlen')) ? 'maxlength="'. (int)$params->get('maxlen') .'"' : ''; ?> style="width:<?php echo $params->get('field_size')?>" name="fields[<?php echo $obj->id?>]" value='<?php echo htmlspecialchars(stripslashes($obj->field_value), ENT_QUOTES, 'UTF-8'  ); ?>'/>
        <?php
        echo "<span>".$params->get('sign_after')."</span>";
    }

    function onBeforeSave(&$value, &$params, $type, $id, $row, &$error)
    {
        if($type != 'text') return;
        if(!$value) return;

        $pregmatch = $params->get('pregmatch');
        $pattern = '';
        switch( $pregmatch ){
            case 'num':
                $pattern = "/[^0-9]/i";
                $value =  preg_replace($pattern, '', $value);
                break;
            case 'text':
                $pattern = "/[^a-zA-Z\W!\@_]+/i";
                $value =  preg_replace($pattern, '', $value);
                break;
            case 'float':
                $parts = explode('.', $value, 2);
                $part1 = $parts[ 0 ];

                if( $part1 == '' || !$part1 ) $part1 = "0";

                $pattern = "/[^0-9]/i";
                $part1 = preg_replace($pattern, '', $part1);

                $part2 = ( @$parts[1] ) ? $parts[1] : '';
                if( $part2 != '' ){
                    $part2 = preg_replace($pattern, '', $part2);
                }
                settype($part1, "string");
                settype($part2, "string");
                $result = $part1;
                $result .= ( $part2 ) ? ".".$part2 : '';
                $value = $result;
                break;
            case 'custom':
                $out = $params->get('custom_ss');
                eval( $out );
                break;
                    
        }


        $db = &JFactory::getDBO();
        $value = $db->getEscaped( trim($value) );

        #echo $value;
        #die;
    }

    function onRenderFieldValue(&$out, &$field, &$params, $type, $user)
    {
        if($type != 'text') return;
        if( !$field->field_value ) return;
        $all = $field->field_value;

        if (JRequest::getCmd('view') != 'article' && $params->get('length', 0)) {
            jimport ('joomla.utilities.string');
            $len = $params->get('length', 0);
            if ($len && JString::strlen($field->field_value) > $len) {
                if ($params->get('allow_html')) {
                    require_once JPATH_PLUGINS.DS.'joomsuite_content_fields'.DS.'html'.DS.'html_stripper.php';

                    $field->field_value = JSHTMLStripper::substr($field->field_value, $len, $params->get('seemore', ''));
                }
                else {
                    $field->field_value = $field->field_value." ";
                    $field->field_value = JString::substr($field->field_value, 0, $len);
                    $field->field_value = JString::substr($field->field_value, 0, JString::strrpos($field->field_value,' '));
                    $field->field_value = $field->field_value." ".$params->get('seemore', '');
                }
            }
        }

        $field->field_value = stripslashes( $field->field_value );

        if ( !$params->get('allow_html', 1) )
        $field->field_value = htmlspecialchars($field->field_value, ENT_QUOTES, 'UTF-8');
        
        $field->field_value = ResHelper::cleanFilterValue($field->field_value, base64_encode($all), $field, $params);

        $out = trim(stripslashes( $params->get('sign_before')." ".$field->field_value." ".$params->get('sign_after')));
    }

    //function onRenderFilter($get, &$filter, $fparam, $filters_type /*, $user*/)
    function onRenderFilter(&$get, &$filter, $params, $category)
    {
        global $mainframe, $option;
        static $results = array();

        $fparam = new JParameter($filter->params);
        $filters_type = $filter->type;

        if($filters_type != 'text') return;

        $get = false;

        $itemid = JRequest::getVar('Itemid');
        $db = & JFactory::getDBO();
        $where = "AND r.published = 1
                  #AND c.published = 1
                  AND (r.extime = '0000-00-00 00:00:00' OR r.extime > NOW())
                  AND r.ctime <= NOW()
                  AND r.client = 'resource'";

        //echo $category; exit;

        switch ($params->get('filters_mode', 1))
        {
            case 1:
                $sql = "SELECT fv.field_value AS value,
                CONCAT(fv.field_value, ' (', COUNT(r.id), ')') AS text
                FROM #__js_res_record_values as fv
                LEFT JOIN #__js_res_record AS r ON r.id = fv.record_id
                LEFT JOIN #__js_res_record_category AS rc ON rc.record_id = fv.record_id
                WHERE fv.field_id = {$filter->id}
                AND rc.catid = {$category} {$where}
                GROUP BY fv.field_value";
                break;
            case 3:
                $category = JRequest::getInt('category_id', $category);
                $ids = ResHelper::getCategoryChildrenIds($category);
                $sql = "SELECT fv.field_value AS value,
                CONCAT(fv.field_value, ' (', COUNT(r.id), ')') AS text
                FROM #__js_res_record_values as fv
                LEFT JOIN #__js_res_record AS r ON r.id = fv.record_id
                LEFT JOIN #__js_res_record_category AS rc ON rc.record_id = fv.record_id
                WHERE fv.field_id = {$filter->id}
                AND rc.catid IN ({$ids}) {$where}
                GROUP BY fv.field_value";
                break;
                
            case 2:
                $sql = "SELECT fv.field_value AS value,
                CONCAT(fv.field_value, ' (', COUNT(r.id), ')') AS text
                FROM #__js_res_record_values as fv
                LEFT JOIN #__js_res_record AS r ON r.id = fv.record_id
                WHERE fv.field_id = {$filter->id} {$where}
                GROUP BY fv.field_value";
                break;
        }

        if($fparam->get('order_by')) $sql .= ' ORDER BY ' . $fparam->get('order_by');

        //echo $sql;
        if(!key_exists($sql, $results))
        {
            //echo 123;
            $db->setQuery($sql);
            $get = $db->loadObjectList();
            $results[$sql] = $get;
        }
        else
        {
            $get = $results[$sql];
        }

        if(is_array($get))
        {
            foreach ($get AS $key => $val)
            {
                $get[$key]->value = base64_encode($val->value);
            }
        }
        //echo $filter->title;
        //print_r($get);
    }
}
?>

-
neoketsordAvatar
Quote
- -
Written by neoketsord VIP on 22 November 2009

Is there an easy option to use the value of another field within the PHP of a field? I tried iFields, but that didn't seem to work... I know I could just write the MySql, but maybe it is possible to make iFields work?

-
adminbeAvatar
Quote
- -
Written by adminbe VIP on 30 November 2009

Hi

I use Resources, Permissions, Touch, Members and Registration. I only use Touch for My Activities, I don't want to use it for Groups, instead I want to use Permissions.

I have a site that allows users to login and they are put in one of 9 groups (set up in permissions)

Every user must then buy a standard or power membership to post articles using Resources (submit articles)

All above is fine.

Now comes my problem

Only 2 of the 9 groups can post articles using one Resources Type (solved no problem)

They post articles using taber plugin form with 6 fields

I need one of the fields in the Resources Type to be custom. I have read the Developer Centre help on making a plugin but I need to know if it is possible to do the following:

create a custom field that has radio buttons that allows the publisher to choose which Permission Groups can view the article.

I think that this would work a little like the Hide Comments but more advanced, so Hide Article. But allows the choice of which groups can see, not just hide from all but publisher and recipient.

The plugin would need to include some sql to select users from the acr table and then allow them access to the article. But it is a little too advanced for me.

Can you help me, and if it costs to do this can you tell me how much?

Thank you

-
avatar
Quote
- -
Written by Erik Roznbeker on 28 April 2010

Great tutorial! Saved my day. Thanks!

-
DeVangelousAvatar
Quote
- -
Written by DeVangelous VIP on 13 August 2010

my brain hurts.....too confusing for me

-
SerhioAvatar
Quote
- -
Written by Serhio STAFF on 16 August 2010

@adminbe VIP It is absolutely what you can do with custom field.

-
Add New Comment
Name:
Email:
Comment:
Attachment
Hide Comment
Security code:
Enter text as you see on image
 
 
What is best way for Download/Installation MightyExtensions?
 


Member Area



Member Activity

We have 2028 guests and 7 members online


MightyTemplate - Professional Joomla Templates