Forums / Developer / help needed on debugging my first basic datatype

help needed on debugging my first basic datatype

Author Message

Stephane Persyn

Tuesday 13 October 2009 8:23:11 am

Hi, guys.

Wondered if someone could take small time amount to check and tell me what am i doing wrong. I am very new to ezpublish, and try to create a datatype for rating any possible content (range is 1 to 5). I tried following the excellent article from Thomas Koch(http://ez.no/developer/articles/creating_datatypes_in_ez_publish_4), as well as existing standard ezpublish datatypes like eZInteger.

Whenever I install my extension, when i want to edit/create/modify a class, I get this page: http://stephane.persyn.free.fr/fre-FR.html

As you can see, debug output isn't giving any hints.

For your comfort, I created a tar.gz file cnoatining the whole mlcndatatype extension structure availabale here: http://stephane.persyn.free.fr/mlcndatatype.tar.gz

You can see here my settings/override/site.ini.append file where i tell ezpublish about my new extension <b>"mlcndatatype" :</b>

[ExtensionSettings]
ActiveExtensions[]=ezgmaplocation
ActiveExtensions[]=ezjscore
ActiveExtensions[]=ezmultiupload
ActiveExtensions[]=ezodf
ActiveExtensions[]=ezoe
ActiveExtensions[]=ezstarrating
ActiveExtensions[]=ezwebin
ActiveExtensions[]=ezwt
ActiveExtensions[]=mlcndatatype

also, you can see below my <b>extension/mlcndatatype/settings/content.ini.append</b> file:

[DataTypeSettings]
ExtensionDirectories[]=mlcndatatype
AvailableDataTypes[]=mlcnrating

..as well as my <b>extension/mlcndatatype/settings/design.ini.append</b> file :

[ExtensionSettings]
DesignExtensions[]=mlcndatatype

Now about the <b>mlcnratingtype.php</b> file, located in <b>extension/mlcndatatype/datatypes/mlcnrating/ </b>:

<?php

/*!
  \class   mlcnRatingType mlcnratingtype.php
  \ingroup mlcnDatatype
  \brief   Prend en charge le type de donnée mlcnRating. En utilisant mlcnRating vous pouvez...
  \version 1.0
  \date    Lundi 12 Octobre 2009 20:44:43
  \author  Stéphane Persyn

  permet aux utilisateurs de donner un score à n'importe lequel de vos objets.
  un operateur de template prévoit de pouvoir agréger les données de score au niveau du parent node
  pour afficher le score moyen obtenu, ainsi que le nombre de votes total.

*/

class mlcnRatingType extends eZDataType
{
    const DATA_TYPE_STRING = "mlcnrating";

    /*!
      Constructeur
    */
    function mlcnRatingType()
    {
        $this->eZDataType( self::DATA_TYPE_STRING, "mlcnRating" );
        $this->IntegerValidator = new eZIntegerValidator();
    }
    /*!
    Validates all variables given on content class level
     \return eZInputValidator::STATE_ACCEPTED or eZInputValidator::STATE_INVALID if
             the values are accepted or not
    */
    function validateClassAttributeHTTPInput( $http, $base, $classAttribute )
    {
        return eZInputValidator::STATE_ACCEPTED;
    }

    /*!
     Fetches all variables inputed on content class level
     \return true if fetching of class attributes are successfull, false if not
    */
    function fetchClassAttributeHTTPInput( $http, $base, $classAttribute )
    {
        return true;
    }
    /*!
     Validates input on content object level
     \return eZInputValidator::STATE_ACCEPTED or eZInputValidator::STATE_INVALID if
             the values are accepted or not
    */
    function validateObjectAttributeHTTPInput( $http, $base, $contentObjectAttribute )
    {
	$classAttribute = $contentObjectAttribute->contentClassAttribute();

	if ( $http->hasPostVariable( $base . "_mlcnrating_data_int_" . $contentObjectAttribute->attribute( "id" ) ) )
        {
            $data = $http->postVariable( $base . "_mlcnrating_data_int_" . $contentObjectAttribute->attribute( "id" ) );
            $data = str_replace(" ", "", $data );

            if ( $data == "" )
            {
                if ( !$classAttribute->attribute( 'is_information_collector' ) and
                     $contentObjectAttribute->validateIsRequired() )
                {
                    $contentObjectAttribute->setValidationError( ezi18n( 'kernel/classes/datatypes',
                                                                         'Input required.' ) );
                    return eZInputValidator::STATE_INVALID;
                }
                else
                    return eZInputValidator::STATE_ACCEPTED;
            }
            else
            {
                $this->IntegerValidator->setRange( "1", "5" );
                $state = $this->IntegerValidator->validate( $data );
                if( $state===1 )
                    return eZInputValidator::STATE_ACCEPTED;
                else
                {
		    $contentObjectAttribute->setValidationError( ezi18n( 'kernel/classes/datatypes',
                                                                         'The number is not within the required range 1 - 5' ) );
		    return eZInputValidator::STATE_INVALID;
		}
            }
        }
        else if ( !$classAttribute->attribute( 'is_information_collector' ) and $contentObjectAttribute->validateIsRequired() )
        {
            $contentObjectAttribute->setValidationError( ezi18n( 'kernel/classes/datatypes', 'Input required.' ) );
            return eZInputValidator::STATE_INVALID;
        }
        else
	  return eZInputValidator::STATE_ACCEPTED;
    }
  
    /*!
     Sets the default value.
    */
    function initializeObjectAttribute( $contentObjectAttribute, $currentVersion, $originalContentObjectAttribute )
    {
        if ( $currentVersion != false )
        {
            $dataInt = $originalContentObjectAttribute->attribute( "data_int" );
            $contentObjectAttribute->setAttribute( "data_int", $dataInt );
        }
        else
                $contentObjectAttribute->setAttribute( "data_int", null );
    }

    /*!
     Fetches all variables from the object
     \return true if fetching of class attributes are successfull, false if not
    */
    function fetchObjectAttributeHTTPInput( $http, $base, $contentObjectAttribute )
    {
        if ( $http->hasPostVariable( $base . "_mlcnrating_data_int_" . $contentObjectAttribute->attribute( "id" ) ) )
        {
            $data = $http->postVariable( $base . "_mlcnrating_data_int_" . $contentObjectAttribute->attribute( "id" ) );
            $data = trim( $data ) != '' ? $data : null;
            $data = str_replace(" ", "", $data);
            $contentObjectAttribute->setAttribute( "data_int", $data );
            return true;
        }
        return false;
    }

    /*!
     Returns the content.
    */
    function objectAttributeContent( $contentObjectAttribute )
    {
        return contentObjectAttribute->attribute( "data_int" );
    }

    /*!
     Returns the meta data used for storing search indeces.
    */
    function metaData( $contentObjectAttribute )
    {
        return contentObjectAttribute->attribute( "data_int" );
    }

    /*!
     Returns the value as it will be shown if this attribute is used in the object name pattern.
    */
    function title( $contentObjectAttribute, $name = null )
    {
        return $contentObjectAttribute->attribute( "data_int" );
    }

    /*!
     \return true if the datatype can be indexed
    */
    function isIndexable()
    {
        return false;
    }

}

eZDataType::register( mlcnRatingType::DATA_TYPE_STRING, "mlcnRatingType" );
?>

Now about the view and edit templates:

<b>1/ view object template located in extension/mlcndatatype/design/standard/templates/content/datatype/view/</b>:

{$attribute.data_int} 

<b<2/ edit object template located in extension/mlcndatatype/design/standard/templates/content/datatype/edit/:</b>

{default attribute_base=ContentObjectAttribute}
<input id="ezcoa-{if ne( $attribute_base, 'ContentObjectAttribute' )}{$attribute_base}-{/if}{$attribute.contentclassattribute_id}_{$attribute.contentclass_attribute_identifier}" 
class="box ezcc-{$attribute.object.content_class.identifier} ezcca-{$attribute.object.content_class.identifier}_{$attribute.contentclass_attribute_identifier}"
type="text"
name="{$attribute_base}_mlcnrating_data_int_{$attribute.id}" 
size="1" 
value="{$attribute.data_int}" />
{/default} 

<b>3/ view class template located in extension/mlcndatatype/design/standard/templates/class/datatype/view/:</b>

/* nothing to do here */ 

<b<4/ edit class template located in extension/mlcndatatype/design/standard/templates/class/datatype/edit/:</b>

/* nothing to do here */ 

I didn't create a specific mlcnRating class, as I don't see any need for that, at the end it's just an even more basic datatype than ezInteger, with specific & known in advance min/max values (1 & 5)....

Again, you can find a zip file containing the whole mlcndatatype extension structure at the link :
http://stephane.persyn.free.fr/mlcndatatype.tar.gz

All help wil be gratly apreciated :)
Cheers,

Stéphane

Gaetano Giunta

Tuesday 13 October 2009 9:52:39 am

Check the php error log. You will likely find the cause of the fatal error that eZ Publish fails to log in your debug output...

Principal Consultant International Business
Member of the Community Project Board

Stephane Persyn

Tuesday 13 October 2009 11:38:23 am

Hi, Gaetano

by reproducing the issue (reloading "mdofy class" page), here's what /var/www.html/ezpublish/var/log/error.log displays:

[ Oct 13 2009 20:15:25 ] [192.168.0.50] index:
Undefined module: var
[ Oct 13 2009 20:15:25 ] [192.168.0.50] error/view.php:
Error ocurred using URI: /var/ezwebin_site/cache/public/images/content_tree-open.gif
[ Oct 13 2009 20:15:44 ] [192.168.0.50] index:
Undefined module: var
[ Oct 13 2009 20:15:44 ] [192.168.0.50] error/view.php:
Error ocurred using URI: /var/ezwebin_site/cache/public/images/content_tree-open.gif

any idea about the var module? As soon as I deactivate my "mlcndatatype" extension through admin interface, everything is going fine again.
any othe "log file" I should sneak into? (no specified logfile specified in php.ini even if "log_errors" is set to "On"...

Gabriel Finkelstein

Tuesday 13 October 2009 12:30:57 pm

You have php error reporting turned off. I get the following syntax errors:

Parse error: parse error in C:\Archivos de programa\EasyPHP 3.0\www\ezpublish-4.1.0\extension\mlcndatatype\datatypes\mlcnrating\mlcnratingtype.php on line 132
Fatal error: eZ Publish did not finish its request

The execution of eZ Publish was abruptly ended, the debug output is present below.
Parse error: parse error in C:\Archivos de programa\EasyPHP 3.0\www\ezpublish-4.1.0\extension\mlcndatatype\datatypes\mlcnrating\mlcnratingtype.php on line 140
Fatal error: eZ Publish did not finish its request

The execution of eZ Publish was abruptly ended, the debug output is present below.

Stephane Persyn

Tuesday 13 October 2009 1:33:53 pm

Thanks, Gabriel.

So I guess you were the weird IP I saw in the logs :) Yes, I can't turn on php logging errors although with php.ini right directive setup (well i guess not).

I have some update though thanks to Bratt who mentored me for some debug testing on IRC. In summary, the synax error code comes from following code in objectAttributeContent, metadata, and title functions:

return contentObjectAttribute->attribute( "data_int" );

Strange enough, is that commenting these lines makes my datatype work (can add a mlcnRating attribute to a new content class, edit the content class, even creat a content object, and modify it.... isn't that WEIRD?

Here's the IRC chat log with Bratt for details. ALL help is still appreciated. I am about to wonder what's the actual role of the 3 functions mentionned above, as if they don't return anything it does't seem to have any impact which i can't beleive one second....

<slaine> Hi, guys.
<slaine> just thought i could say hello on irc, and ask for some help...
<slaine> does anyone can actually help me understand what's going on with my veeeery baaaaasic datatype. 
<slaine> See forum post : http://ez.no/developer/forum/developer/help_needed_on_debugging_my_first_basic_datatype
<slaine> I am sue it's (as usual) a very basic mistake, but still i am stuck. as a newbie, i might have all insight on the fundamental concepts.
<slaine> pls read "I might NOT have all insight" :)
<slaine> is there any "up & running" people here? :)
<Bratt> slaine: Gaetano told you to check the _php_ error log, not eZ Publish error log
<Bratt> slaine: Check Apache error log file?
<slaine> no didn't. let me check :)
<slaine> Bratt: is that talking to you: [Tue Oct 13 20:50:37 2009] [error] [client 192.168.0.50] PHP Parse error:  syntax error, unexpected T_OBJECT_OPERATOR in /var/www/html/ezpublish/extension/mlcndatatype/datatypes/mlcnrating/mlcnratingtype.php on line 132, referer: http://adminmalicorn.dyndns.org/class/grouplist
<Bratt> slaine: Yepp, you have a syntax error in your code. Fix it :)
<slaine> Bratt: how can this be a syntax error: return contentObjectAttribute->attribute( "data_int" );
<slaine> Sorry if it's obvious, but I am very newbie :)
<Bratt> It's not. Try commenting it out, see if it works then
<scrieler> Bratt: I got a ez4.2 install, yeeeeeeeeeehaw :D
<slaine> Bratt: now i get same error a few line below first. same error, same cause, same "return contentObjectAttribute->attribute( "data_int" );"
<slaine> in fact I used this return values for functions: objectAttributeContent, metadata, and title
<slaine> strange enough, as this is the exact copy of eZInteger datatype code
<Bratt> Did you copy the file, or copy and paste in an editor?
<slaine> copy paste i beleive... don't tell me I copied some hidden caracters... :)
<Bratt> Did you copy some hidden characters? :)
<Bratt> Try rewriting the line by hand
<slaine> Bratt: no... now the httpd/error.log shows again an issue on first occurence of faulty code (rewrited by hand)...
<Bratt> Hmmm
<slaine> Bratt: I guess theres something else in my code elsewhere that makes this return... bla bla messing up
<slaine> btw, what's a T_OBJECT_OPERATOR?
<Bratt> Try rewriting it
<Bratt> return "test"; or something
<slaine> now comes back to line 140 on second occurence (as first is now return "test";)
<Bratt> Hm....weird
<slaine> pff as usual with me :)
<Bratt> Ok, comment out both lines, and var_dump( $contentObjectAttribute );
<slaine> ok
<slaine> Bratt: now I can access the page (modify class) without errors, i can even see my mlcnRating datatype appear in the dropdown list. issue is that i can't use it indeed, as I return no value from function objectAtributeContent...
<slaine> anywhere to look (i suppose var_dump shows details on the variable contentObjectAttribute?)
<Bratt> slaine: But do you see the var dump?
<Bratt> It should be in the top of the html page, I would think
<slaine> Bratt: I see no var dumps anywhere on the page. tried even to add a mlcnRating, on a new class, said ok, accessed the view template aso.. no var_dumps
<Bratt> Hmm
<Bratt> Add a die(); after the var_dump, then you should see it :)
<slaine> it doesn't show up :)
<Bratt> If you publish an object of the class?
<slaine> strange enough, i can create actual content, value seems to be actually stored, and can be modified... can you explain this magic?
<Bratt> Hmm...no
<slaine> look yourself: http://stephane.persyn.free.fr/fre-FR3.html
<slaine> nouvelle classe is just involving an ezinteger, and a mlcnRating...
<slaine> sorry i didn't upload the folder with all images and all the stuff..
<slaine> but with only the html file you can  see the "view content class" page
<slaine> as well as the debug output clearly showing ez accessed the mlcnrating.tpl file (content/view one)
<slaine> Can't understand what's going on...
<Bratt> Me neither. Try the forums again, write an update with the new info
<slaine> ok thanks still for your guidance..

Bruce Morrison

Tuesday 13 October 2009 6:24:12 pm

Hi Stephane

You may have already worked it out but the contentObjectAttribute var in mlcnRatingType::objectAttributeContent & mlcnRatingType::metaData is missing a leading '$' and should read

    /*!
     Returns the content.
    */
    function objectAttributeContent( $contentObjectAttribute )
    {
        return $contentObjectAttribute->attribute( "data_int" );
    }

    /*!
     Returns the meta data used for storing search indeces.
    */
    function metaData( $contentObjectAttribute )
    {
        return $contentObjectAttribute->attribute( "data_int" );
    }

Just like the mlcnRatingType::title method.

Cheers
Bruce

My Blog: http://www.stuffandcontent.com/
Follow me on twitter: http://twitter.com/brucemorrison
Consolidated eZ Publish Feed : http://friendfeed.com/rooms/ez-publish

Gaetano Giunta

Wednesday 14 October 2009 1:11:56 am

@Stephane - not sure if you can change error logging or not in php.ini, but, fyi, if there is no error log specified and error logging is set to on, the php errors will be found in the Apache error log

Principal Consultant International Business
Member of the Community Project Board

Stephane Persyn

Wednesday 14 October 2009 1:50:40 pm

Gaetano, Bruce:

Thanks for your replies... and yes you both are right :)

Gaetano: Yes, I've found the error logging through apache error log, and saw there was 2 errors, while I had 3 times same "incriminated" code.

Bruce: Yes, I had worked it out very few minutes since my last post. It was a silly mistyping error. Next time, I'll use a better text editor with php code highlighting. It would have saved me a lot of time.

Thanks to all people having helped me. The good news, is that means it was not due at all to the fact I couldn't fully figure out how datatypes work, as I was believing first.

Now, let's optimize this draft datatype, and go on with template operators.

Once I'll feel more confident, I'll be glad to help others (my turn).

Cheers,

Stéphane