Bug #23514 See Comments

Advanced conditional parsing seems to interfere with simple custom fieldtypes

Version: 4.1.1 Reporter: timoteus

This is quite a tricky bug which is reproducable with a completely new installation, a simple selfwritten fieldtype, a channel, one (or more) entry(ies) and a simple template with advanced conditionals (+php on input for an easier change of the amount of conditionals).

If you have to write your own fieldtype (e.g. My Fieldtype) with complex data and you want to output it with a tag pair {myfieldtype}output{/myfieldtype} it works no matter what, but if you use a second tag, e.g. {myfieldtype:test}output{/myfieldtype:test} it works just for a limited amount of advanced conditionals (so it seems?). Although its reproducable, I have no clue, why this is happening.

To test this I have written a simple fieldtype (ft.my_fieldtype.php and addon.setup.php) and template (change the limit from 50 to e.g. 100 and the tag pair won’t work anymore):

ft.my_fieldtype.php:

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

/**
 * For testing
 */
class My_fieldtype_ft extends EE_Fieldtype {
    
    // general info
    var $info = array(
     "name"  => "Test Fieldtype",
     "version" => "0.0.1"
    );
    
    // for tag pairs
    public $has_array_data = TRUE;
    
    // prefix to avoid duplicates
    private $prefix = "mft:";
    
    // --------------------------------------------------------------------

    /**
     * Install Fieldtype
     *
     * @access public
     * @return default global settings
     */
    function install() {
     return array(
      'field_wide'  => TRUE  // If your fieldtype needs a wide style on the publish form, like Grid or a Textarea, then be sure to include 'field_wide' => TRUE in your settings array.
     );
    }//install() end
    
    // --------------------------------------------------------------------
    
    /**
     * Update Fieldtype
     *
     * This function performs any necessary db updates when the extension
     * page is visited
     *
     * @return  mixed   void on update / false if none
     */
    function update($current = "") {
     if ($current == '' OR $current == $this->info["version"]) {
      return FALSE;
     }
    
     ee()->db->where( "name", "my_fieldtype" );
     ee()->db->update( "fieldtypes", array("version" => $this->info["version"]) );
    }//update end
    
    // --------------------------------------------------------------------
    
    /**
     * Check if the fieldtype will accept a certain content type
     *
     * For backward compatiblity, all fieldtypes will initially only
     * support the channel content type. Override this method for more
     * control.
     *
     * @param string  The name of the content type
     * @return bool   Supports content type?
     */
    public function accepts_content_type($name) {
     return ($name == 'channel');
    }//accepts_content_type end
    
    // --------------------------------------------------------------------
    
    /**
     * Display Field on Publish
     *
     * @access public
     * @param existing data
     * @return field html
     *
     */
    function display_field($data) {
     $inputData = array(
       "type" => "text",
       "name" => $this->field_name,
       "id" => $this->field_name,
       "value" => isset($data) ? $data : "test"
     );
     
     return "<div>".form_input($inputData)."</div>";
    }//display_field end
    
    // --------------------------------------------------------------------
    
    /**
     * Validate the posted data.
     *
     * @param mixed $data
     *
     * @return mixed $result Error message in case of failed validation.
     */
    public function validate($data) {
     return TRUE;
    }//validate end
    
    // --------------------------------------------------------------------
    
    /**
     * Save the field
     *
     * The data you return will be saved and returned to your field on
     * display on the frontend and when editing the field. This is the
     * field that is processed on search.
     *
     * If you want to store data in your own table, please use post_save
     * when the entry/content id is available.
     *
     * @param mixed  data submitted with the field_name, arrays allowed
     * @return string data to store
     */
    public function save($data) {
     return $data;
    }//save end
    
    // --------------------------------------------------------------------
    
    /**
     * Replace the field tag on the frontend.
     *
     * @param string Stored data for the field - contains the field data (or prepped data, if using pre_process)
     * @param array  The tag's parameters
     * @param mixed  If the tag is a pair, the tagdata (data between tag == for tag pairs). Otherwise FALSE.
     * @return string Parsed tagdata
     */
    public function replace_tag($data, $params = array(), $tagdata = FALSE) {
     
     if(!$tagdata) {
      return "single tag";
     }
     
     return "paired tags";
    }//replace_tag
    
    public function replace_test($data, $params = array(), $tagdata = FALSE) {
     
     if(!$tagdata) {
      return "test single tag";
     }
     
     return "test paired tags";
    }//replace_tag
    
}
// END My_fieldtype_ft class

addon.setup.php:

<?php
return array(
    'author'  => 'ilab',
    'author_url' => '-',
    'name'   => 'Test Fieldtype',
    'description' => 'Advanced Conditional Test',
    'version'  => '0.0.1',
    'namespace'  => 'ilab\test',
    'settings_exist' => FALSE
);

test-template:

{exp:channel:entries channel="my_channel" disable="member_data|pagination|relationships" dynamic="no" status="open" limit="1"}
{title}


{testfield:test}
to replace
{/testfield:test}



<?
for ($i = 1; $i < 50; $i++) { //change limit to e.g. 100 and it won't work
    echo $i.': {testfield}{if "{testfield}" == ""}mtf is empty{/if}
';
}
?>





{/exp:channel:entries}
.(JavaScript must be enabled to view this email address)

ExpressionEngine News!

#eecms, #events, #releases