Forums / General / Object Relations

Object Relations

Author Message

Gabriel Ambuehl

Wednesday 24 August 2005 6:56:32 am

I'm coming to think this is probably some sort of a bug. Or maybe it's intentional but in any case, different behavior would probably be better.

I'll try to figure out what to do when I get the time. In the mean time if someone feels like writing a bug report, do so.

Visit http://triligon.org

Xavier Dutoit

Wednesday 24 August 2005 7:38:37 am

I wasn't aware of this new function on 3.6.

Roberto, could you try using
http://ez.no/download/changelogs/ez_publish_3_6/new_features/advanced_related_objects

{def $objects=fetch( content, reverse_related_objects, hash( object_id, $node.contentobject_id, attribute_identifier, 'books/authors' ) )}

Play around the "books/authors" as the attribute if it doesn't work.

As if you want to modify the default behavior to revert it to how it worked before (put them into the reverse_related list) :

modify kernel/classes/ezcontentobject.php

    function &reverseRelatedObjectList( $version = false, $toObjectID = false, $
attributeID = 0 )
    {
...
       $relatedObjects =& $db->arrayQuery( "SELECT DISTINCT ezcontentobject.*
                                   FROM
                                     ezcontentobject, ezcontentobject_link
                                   WHERE
                                     ezcontentobject.id=ezcontentobject_link.fro
m_contentobject_id AND
                                     ezcontentobject.status=" . EZ_CONTENT_OBJEC
T_STATUS_PUBLISHED . " AND
                                     ezcontentobject_link.to_contentobject_id=$toObjectID AND
                                     ezcontentobject_link.from_contentobject_version=ezcontentobject.current_version );


Basically, delete "AND contentclassattribute_id=$attributeID"

at the end of the query.

X+

http://www.sydesy.com

Roberto Kirschbaum

Wednesday 24 August 2005 9:06:18 am

Xavier,

Before trying

{def $objects=fetch( content, reverse_related_objects, hash( object_id, $node.contentobject_id, attribute_identifier, 'books/authors' ) )}

I changed kernel/classes/ezcontentobject.php as you said. I assumed this was necessary before I tried the fetch function. Did I assume wrong?

Anyways, after I changed the file and cleared the chaches, I erased some relations created before this kernel change, and then created new relations. For my susprise, when I go to the admin page for either books or authors, I still get:
//Relations [0]
//Related objects [0]
//The item being viewed does not make use of any other objects.
//Reverse related objects [0]
//The item being viewed is not in use by any other objects.

So, what change of behaviour should I have looked for, after changing the kernel file?

thanks you all for the efforts so far!
Roberto

PS: I tried the suggested function
(Note: Authors [Enhanced Object relation] (id:227))

        {def $objects=fetch( content, reverse_related_objects, hash( object_id, $node.contentobject_id, attribute_identifier, 227 ) )}
            {foreach $objects as $object}
                 {$object.object.name}<BR />
            {/foreach}
        {undef $objects}

but to no avail...

Xavier Dutoit

Wednesday 24 August 2005 1:30:10 pm

Hi Roberto,

To clarify :
1) the patch was supposed to let you get your reverse_related_contentobject_array properly filed
2) the fetch reverse_related_objects (+attribute parameter) was supposed to work without the patch.

You told us that the table is properly filed with the relations, right ?

I'm afraid we need to dig into the SQL to understand why it doesn't work.

in ezcontentobject_link, find the links created by eor for one object.

in your site.ini.append.php
add into [DatabaseSettings]
SQLOutput=enabled
and enable the general debug if it isn't already done.

clear the caches and reload the page.

You're going to have a few zillions sql queries.
One of them is the one to get the reverse related objects.
(search ezcontentobject_link) it should make sense.

It should tell you what's wrong...

Is this web site accessible from outside ? I can look at it if you prefer contact me (xavier AT sydesy DOT com).

Good luck.

X+

http://www.sydesy.com

Roberto Kirschbaum

Thursday 25 August 2005 7:53:22 am

Xavier (and all)

The fetch reverse_related_objects (+attribute parameter) <i>is working!</i> I actually made a mistake using it. It seems though that this fetch function doesn't have a "sort_order" parameter, so I am working to make the books appear in alphabetical order. I'm almost there, but if anyone knows of a good solution for this, (ie, a simple way to sort the output of fetch reverse_related_objects) please let me know.

As to
"1) the patch was supposed to let you get your reverse_related_contentobject_array properly filed"
I still don't see the effects of applying the patch as when I look a either books or authors in the admin interface, I get
//Relations [0]
//Related objects [0]
//The item being viewed does not make use of any other objects.
//Reverse related objects [0]
//The item being viewed is not in use by any other objects.

But then, this doesn't matter too much, as the problem itself is solved (showing the books by an author). I thank you guys so much for your time and patience and I learned a lot with you.

Xavier Dutoit

Thursday 25 August 2005 10:08:50 am

Hi,

Glad to see you made it.

For the record (and so I can update the documentation), could you post the code of the fetch that did it ?

X+

http://www.sydesy.com

Gabriel Ambuehl

Thursday 25 August 2005 10:36:23 am

As for why the fetch doesn't have a sort_order: a relation is, at the bottom of it, really nothing more than the ID the object is pointing to. So making sort_order work is somewhat complicated as you don't know just what sort of object you'll be dealing with in advance (tho sorting by the usual suspects should still be possible).

You might want to submit this as improvement suggestion to ez if you don't want to hack the kernel yourself.

Visit http://triligon.org

Nicolay Camargo

Thursday 25 August 2005 2:31:40 pm

Hello:
Very interesting discussion, I'm working in a related project, I need create relations in a code procedure, "automatic relations" for example when i create an object of the class A then the system add Related Objects of class B, perhaps from a button. I need write php code?. Any help

Thanks,

Nicolay
Corenet S.A.
Bogota - Colombia
www.corenet.net.co
[email protected]

newave france

Friday 26 August 2005 6:08:50 am

Hello,

I had the same problem yesterday but I did not find the solution.

Please Roberto, could you post the code of the fetch that did it ?

Is it necessary to change the code like Xavier tell us or not ?

Xavier are you french ? If you speak french are you on the frence communauty too of ez ?

Is this extrension ok if the site have more than 1 000 categories used to make relations with article, news, products ? Is ez powerful enough for taht kind of use ?

Thanks...

Gabriel Ambuehl

Friday 26 August 2005 3:47:16 pm

I think something else, pretty weird is going on here in 3.6.1.

My enhanced object relations show up just fine in the content object (admin as well as frontend) but if I activate relations display in the admin GUI, I see the following (I have three different relations defined, each pointing to one object):

Relations [0]
Related objects [0]
The item being viewed does not make use of any other objects.
  Reverse related objects [0]
The item being viewed is not in use by any other objects.

This is definitely NOT what should be happening.

Visit http://triligon.org

Gabriel Ambuehl

Friday 26 August 2005 4:00:41 pm

I can tell you WHY it happens:

SELECT
                                               count( ezcontentobject_link.from_contentobject_id ) as count
                                             FROM
                                               ezcontentobject,
                                               ezcontentobject_link
                                             WHERE
                                               ezcontentobject.id=ezcontentobject_link.to_contentobject_id AND
                                               ezcontentobject.status=1 AND
                                               ezcontentobject_link.from_contentobject_id='141' AND
                                               ezcontentobject_link.from_contentobject_version='1' AND
                           contentclassattribute_id=0

and similarly

SELECT count( DISTINCT ezcontentobject.id ) AS count
                                             FROM
                                               ezcontentobject, ezcontentobject_link
                                             WHERE
                                               ezcontentobject.id=ezcontentobject_link.from_contentobject_id AND
                                               ezcontentobject.status=1 AND
                                               ezcontentobject_link.to_contentobject_id=141 AND
                                               ezcontentobject_link.from_contentobject_version=ezcontentobject.current_version AND
                           ezcontentobject_link.contentclassattribute_id=0

Look at the last line of each query. Personally, I don't think it should be there, at all! Each object that points to some other object should list that fact, no matter if it's on the object or the attribute fact!

Visit http://triligon.org

Gabriel Ambuehl

Saturday 27 August 2005 4:10:50 am

I reported it as a bug, please see http://ez.no/bugs/view/7093 and comment on it if you have any additional things I didn't mention.

Visit http://triligon.org

Roberto Kirschbaum

Monday 29 August 2005 6:12:19 am

Hello,

There really seems to be nothing wrong with the fetch function. But I agree that there must be a bug as to why don't the relations show in the admin GUI?

For the records and for those who have the same needs as I do, here's what I've done so far:

I have an override template for the AUTHORS class, which shows the Author's Name, Birth and Death dates, his Biography, and then Links to his available books. Books are in another class, "book", and here's what I did in order to show the books, alphabetically ordered:

        {def $sAutorId=$node.object.id}

        {* GETTING THIS AUTHOR'S BOOKS *}
        {* Note: Authors [Enhanced Object relation] (id:227) *}
        {def $books=fetch( content,
                           reverse_related_objects,
                           hash( object_id, $node.contentobject_id,
                                 attribute_identifier, 227
                                )
                          )
        }


        {* BUILDING AN ARRAY WITH OBJECT_IDs AND BOOKS' TITLES *}
        {def $japassou=0}
        {def $name='?'}
        {def $nodeid=0}
        {foreach $books as $thisbook}
          {set $name=$thisbook.name}
          {set $nodeid=$thisbook.id}
          {if eq($japassou,0)}
            {set $japassou=1}
            {* 1ST TIME: def ARRAY $lista *}
            {def $lista=array($nodeid,$name)}
          {else}
            {* N-th TIME: SET/APPEND TO ARRAY $lista *}
            {set $lista=$lista|append($nodeid,$name)}
          {/if}
        {/foreach}
        {undef $books, $thisbook, $name, $nodeid, $japassou}

        {* ORDERING OBJECTS/TITLES ARRAY BY TITLE*}
        {* "sort" operator returns this kind of array: *}
        {* Array ( [0]=> 6 [1] => 112 [2] => Casa Velha [3] => 111 [4] => Memórias Póstumas de Brás Cubas [5] => 130 [6] => Sempre não ) *}
        {* i.e., an array(objectid, title, objectid, title...) titles already alphabetically ordered, first cell= sizeof array *}
        {set lista = $lista|sort}

        {* SWEEPING THE ARRAY AND BUILDING THE HREF LINKS *}
        {* Note: $lista.0 contains the size of the array *}
        {def $sizeoflista=$lista.0}
        {def $i=1}
        {def $j=1}
        {def $titulo=''}
        {while lt($i,$sizeoflista)}
          {* WE NEED THE OBJECT'S NODE_ID, NOT ITS OBJECT_IDs, SO... LET'S GET IT *}
          {def $object=fetch( 'content', 'object', hash( 'object_id', $lista[$i] ) )}
          {def $nodeid=$object.main_node_id}
          {undef $object}
          {set $j=inc($i)}
          {set $titulo=$lista[$j]|wash}
           <a href={concat('/content/view/full/',$nodeid)|ezurl}>{$titulo}</a><BR />
          {undef $object, $nodeid, $titulo}
          {set $i=sum($i,2)}
        {/while}

        {undef}

And here is the sort function, which I put in index.php:

function my_sort($array) {
  $i=0;
  while ($i<sizeof($array)) {
    $j=$i+1;
    $node=$array[$i];
    $nome=$array[$j];
    $newarray["$node"]=$nome;
    $i=$i+2;
  }
  asort($newarray);
  reset($newarray);
  $lista="";
  while (list ($key, $val) = each ($newarray) ) {
    if ($lista<>"") {
      $lista.="ÿ";
    }
    $lista.=$key."ÿ".$val;
  }
  $newarray=explode("ÿ",$lista);

  array_unshift($newarray, sizeof($newarray)); // puts sizeof $newarray into it's 1st cell

  return $newarray;
}

I hope this helps. If anyone could do all this in a more ellegant way, please share!

Roberto

Kirill Subbotin

Tuesday 30 August 2005 3:00:06 am

Hi All!

I'm the person who added this "reverse related by the attribute" fetch function to ez publish, so I feel like I'm able to answer all of your questions. ;) But first, let me explain it all.

As you know, it was unpossible before (since "related objects" datatype had been added), so we decided to add such functionality to 3.6. But of course our main rule, as always, was to keep an old functionality. We have to obey it when we add anything new, in order to make it possible to upgrade from the previous version. So we couldn't change the behavior of the "reverse_related_contentobject_array" function. It never returned reverse related objects made by content object attributes, cause it was unpossible at all, as they were not stored in a corresponding database table. So it just work like it worked before. "reverse_related_objects" fetch function had been added for fetching reverse relations made by the specific attribute.

The one thing I can agree with you is that it would be good to display such relations in the admin interface with pointing attributes' names/numbers.

Now its just unpossible, because we have no function to fetch ALL relations, so I think it should be added. We could do it by some specific value of the 'attribute_identifier' parameter of the 'reverse_related_objects' fetch function. But as 0 is used and it means 'regular' relations, we can't use it. Or we could add another fetch function.

Also I agree that there is a confusion for a newbie and even expirienced users that object relations can be fetched with 3 different methods:
1) Functional attributes (like related_contentobject_array) for normal relations.
2) object.data_map.* for straight attribute relations.
3) reverse_related_objects fetch function for reverse relations.

I could suggest to make another fetch functions for all types of relations, so it could be universal method of fetching any relations which could be quite reasonable. I will contact our management and we probably implement it. What do you think ?

Kirill Subbotin

Tuesday 30 August 2005 3:05:20 am

2 Roberto:

If you want all relations to be displayed in admin interface and returned by 'related_contentobject_array' now you can do a simple hack:

In /kernel/classes/ezcontentobject.php find the function 'relatedContentObjectArray' for related or 'reverseRelatedObjectList' for reverse-related objects and just remove the line "contentclassattribute_id=$attributeID" from SQL query.

Xavier Dutoit

Tuesday 30 August 2005 3:39:21 am

Hi Kirill,

I'm the person who created the enhanced object relation, so I feel like I'm able to disagree with you when you says that "It never returned reverse related objects made by content object attributes [...]as they were not stored in a corresponding database table" ;)

The eor did that, and one of the main reason to create it was to be able to get the relations set by an attribute into related_contentobject_array and reverse.

As Gabriel said, the best solution IMO is to list all the relations into the arrays (and counts). As it doesn't seem to be an option,I suggest :

1) To add a new boolean parameter (all) to the existing fetch functions
reverse_related_objects_count, reverse_related_objects.

by defaut, that's false, and it you true() it, it will fetch all the relations, no matter the attribute.

{def $objects_count=fetch( content, reverse_related_objects_count, hash( object_id, $node.contentobject_id, all, true() ) )}

2) to add two new fetch functions related_objects_count and related_objects
With the same arguments than the reverse_related ones

3) to obsolete the arrays into the node.

Any thought ?

X+

http://www.sydesy.com

Gabriel Ambuehl

Tuesday 30 August 2005 4:35:44 am

I fully agree with Xavier here. It did in FACT return everything (simply because it didn't know about the attribute_id stuff Xavier had added way back when enhancedobjectrelation was first implemented).

So in essence, you didn't preserve backward compatibility with this (at least not in all ways).

I still think that the admin interface should display them all (for reasons pointed out above, it did so in the past) as it's rather confusing for people not to see the relations.

In order to keep the API as it is, why not simply interprete negative ints passed to the attribute_identifier parameter as a wildcard to return EVERYTHING? If adding a boolean for "return_all" is possible, that would be much preferred of course.

OTOH, a new function to deal with this things wouldn't be all bad either as then it could return a array of the following format:

$reverse_related_object=array();
$reverse_related_object['contentobject_level']=array(/*all non attribute specific relations/*)
$reverse_related_object['attribute_identifier#1']=array(/*all  attribute specific relations for attribute_identifier#1/*)
$reverse_related_object['attribute_identifier#2']=array(/*all  attribute specific relations for attribute_identifier#2/*)

Or maybe, providing the same info but in a different structure:

$reverse_related_object=array();
$reverse_related_object[]=array("attribute_idenfier",  $related_object)

Am I making sense?

And while we're at it, the analog functionality for "forward" relations could potentially be quite handy, too.

Visit http://triligon.org

Kirill Subbotin

Tuesday 30 August 2005 4:58:33 am

2 Xavier:

Of course I meant it was impossible by ez publish itself, not by your extension.

And yes, your propositions have sense, but in this case there is still no way to determine which type of relations was used cause we get only an array of content objects. We need it for example to display reverse relations in admin interface. I think we also need another mode for this fetch function, which would return more complex structure.

Kirill Subbotin

Tuesday 30 August 2005 5:09:01 am

2 Gabriel:

You first structure type makes sense. Also I think we need additional parameter to enable this advanced structure. And of course this feature should be added to both reverse and straight functions.
And also.. should we use attribute_identifier or attribute_id in the returned array ?

Gabriel Ambuehl

Tuesday 30 August 2005 5:18:34 am

Most functions accept either the id or the identifier. Ideally it treats ints as IDs and strings as identifiers, I guess.

Adding two new fetch functions is likely the best way to do it.

Visit http://triligon.org