Forums / General / Object Relations

Object Relations

Author Message

Roberto Kirschbaum

Monday 22 August 2005 5:06:29 pm

Hello friends,

I am setting up a virtual library with full-texts.

I have a "Books" Content Class whith basically this structure (I've ommitted some attributes for cleanliness' sake):
1. Title [Text line] (id:211)
2. Authors [Object relations] (id:216)
3. Pdf [File] (id:218)

I have a folder where I store objects of another
Content Class - "Authors". So the "books" content class makes reference to the "Authors" content class using the "Authors" attribute. This way I can have "books" related to "authors" and then,
when I go to an Author's Page, say "Shakespeare", the system should show his biography and then list the books by shakespeare available in the library.

What I haven't been able to do is a FETCH with which I would be able to discover all of Shakespeare's works available in the website.

What I imagine I would have to do is:
Once I have Shakespeare's object ID from the Authors' folder, I would sweep the Books folder looking for those objects which have an OBJECT RELATION with the author Shakespeare, and then list the results, linking to the available books.

I'm a newbie in EZP, so I tried everything I could find in the DOCs, but I suspect I missed something, as I couldn't do what I want. Can someone please help me?

Thanks so much!
Roberto

Gabriel Ambuehl

Tuesday 23 August 2005 12:13:24 am

Take a look at the enhancedobjectrelation data type in the contribution section which is designed to allow exactly this.

Visit http://triligon.org

Deane Barker

Tuesday 23 August 2005 5:41:50 am

I think they built this into 3.6. See this change note.

http://ez.no/download/changelogs/ez_publish_3_6/new_features/advanced_related_objects

<i>Reverse related objects:
You can get an array of reverse related objects made with attributes using new template content fetch function 'reverse_related_objects' and get their quantity with 'reverse_related_objects_count' function. These function have two parameters:

* 'object_id'
* 'attribute_identifier'.

You can use either string attribute identifier or a numeric attribute ID. This parameter is not required and it's default vaule is zero, which is similar to 'reverse_related_contentobject_array' functional attribute of a content object. </i>

Roberto Kirschbaum

Tuesday 23 August 2005 10:37:17 am

Deane, thanks for the hint. I tried to use it but the examples were so synthetic that I felt too dumb to use... some of the documentation seems to be made for people who already know the stuff so they don' actually need the documentation!

Gabriel, thanks for your hint too. I installed EOR according to the instructions. However, when I try to insert an Enhanced Object relation attribute into my Book class, I am not able to define anything but the attribute's name and identifier. No place to chose the class of related objects:

6. new attribute6 [Enhanced Object relation] (id:225)

Name:

Identifier:

Required Searchable Information collector

What am I missing???

Gabriel Ambuehl

Tuesday 23 August 2005 10:52:57 am

Did you clean the cache? You should be able to set the class type, for damn sure.

Visit http://triligon.org

Roberto Kirschbaum

Tuesday 23 August 2005 11:33:02 am

Yes, it was the cache flushing. ;-|

Now, I've added the "AUTHORS" EOR attribute to
my BOOKS class. It works fine, allowing me to assing AUTHORs to BOOKs.

I then opened some BOOKs and assigned them some authors.

Now I want to access one author and see
all the BOOKs which have this author assigned
to them.

I tried the example code (see below) but it didn't show anything. Of course, I think there's something missing, for example, where should I say that the EOR attribute name I am dealing with is "AUTHORS"? I know that I could spend some more hours trying to find this out, but at this point I'd gladly accept some more help, as I am stuck on this subject for days...

{let reverse_related=$node.object.current.reverse_related_object_list}
{$reverse_related|attribute(show)}

<ul>
{section name=ReverseObject loop=$reverse_related show=$reverse_related}
<li><a href={$ReverseObject:item.main_node.url_alias|ezurl}>{$ReverseObject:item.name}</a></li>
{/section}

{/let}

Gabriel Ambuehl

Tuesday 23 August 2005 12:23:09 pm

reverse relations are always attribute unspecific (I might change that eventually). The code on the EOR page should work for all I know.

Visit http://triligon.org

Roberto Kirschbaum

Tuesday 23 August 2005 12:45:00 pm

I am about to commit suicide... why is EZP sooooooo hard? It's like learning Japanese in braile...

Trying to investigate, I put this code into the template:

{let reverse_related=$node.object}
{$reverse_related|attribute(show,1)}

And It shows:
(snip)
related_contentobject_array array Array(0)
related_contentobject_count string 0
reverse_related_contentobject_array array Array(0)
reverse_related_contentobject_count string 0
(/snip)

Isn't it suspicious that these arrays are zeroed?

When I go to the Admin interface and look at the BOOKs, I can actually SEE the assigned authors (from AUTHORS class)! When I access the book on the public website I AM able to see the related author(s). SO Why then when I put the example EOR code on the AUTHOR template, it just won't show thw related books? I must be doing something wrong, but if I knew what, I would correct it!

Please I beg for help!

Gabriel Ambuehl

Tuesday 23 August 2005 12:47:42 pm

What does

{$node|attribute(show)} 

display

Also try just attribute(show) without depth limits.

Visit http://triligon.org

Roberto Kirschbaum

Tuesday 23 August 2005 12:57:57 pm

$node|attribute(show) Shows:

<b>Attribute Type Value </b>
node_id string 128
parent_node_id string 105
main_node_id string 128
contentobject_id string 126
contentobject_version string 1
contentobject_is_published string 1
depth string 4
sort_field string 2
sort_order string 0
priority string 0
modified_subnode string 1124718233
path_string string '/1/2/121/105/128/'
path_identification_string string 'textos/por_autor/teofilo_braga_joaquim_teofilo_fernandes_braga'
remote_id string '667e11c85c70748ff26185247b0b67f5'
is_hidden string 0
is_invisible string 0
name string 'Teófilo Braga (Joaquim Teófilo Fernandes Braga)'
data_map array Array(5)
>nome object[ezcontentobjectattribute] Object
>foto object[ezcontentobjectattribute] Object
>biografia object[ezcontentobjectattribute] Object
>nascimento object[ezcontentobjectattribute] Object
>morte object[ezcontentobjectattribute] Object
object object[ezcontentobject] Object
>id string 126
>section_id string 6
>owner_id string 14
>contentclass_id string 25
>name string 'Teófilo Braga (Joaquim Teófilo Fernandes Braga)'
>is_published string 0
>published string 1124718233
>modified string 1124718233
>current_version string 1
>status string 1
>remote_id string 'a881e8d838c32f5845675e6720a86638'
>current object[ezcontentobjectversion] Object
>versions array Array(1)
>author_array array Array(1)
>class_name string 'Autor'
>content_class object[ezcontentclass] Object
>contentobject_attributes array Array(5)
>owner object[ezcontentobject] Object
>related_contentobject_array array Array(0)
>related_contentobject_count string 0
>reverse_related_contentobject_array array Array(0)
>reverse_related_contentobject_count string 0
>can_read boolean true
>can_create boolean false
>can_create_class_list array Array(0)
>can_edit boolean false
>can_translate boolean false
>can_remove boolean false
>can_move boolean false
>can_move_from boolean false
>data_map array Array(5)
>main_parent_node_id string 105
>assigned_nodes array Array(1)
>parent_nodes array Array(1)
>main_node_id string 128
>main_node object[ezcontentobjecttreenode] Object
>default_language string 'por-BR'
>content_action_list boolean false
>class_identifier string 'autor'
>class_group_id_list array Array(1)
>match_ingroup_id_list boolean false
subtree array Array(0)
children array Array(0)
children_count string 0
contentobject_version_object object[ezcontentobjectversion] Object
>id string 621
>contentobject_id string 126
>creator_id string 14
>version string 1
>status string 1
>created string 1124718029
>modified string 1124718029
>workflow_event_pos string 0
>user_id string 0
>creator object[ezcontentobject] Object
>name string 'Teófilo Braga (Joaquim Teófilo Fernandes Braga)'
>version_name string 'Teófilo Braga (Joaquim Teófilo Fernandes Braga)'
>main_parent_node_id string 105
>contentobject_attributes array Array(5)
>related_contentobject_array array Array(0)
>reverse_related_object_list array Array(0)
>parent_nodes array Array(1)
>can_read boolean false
>data_map array Array(5)
>node_assignments array Array(1)
>contentobject object[ezcontentobject] Object
>language_list array Array(1)
>translation object[ezcontentobjecttranslation] Object
>translation_list array Array(0)
>complete_translation_list array Array(1)
>temp_main_node object[ezcontentobjecttreenode] Object
sort_array array Array(1)
>0 array Array(2)
can_read boolean true
can_create boolean false
can_edit boolean false
can_hide boolean false
can_remove boolean false
can_move boolean false
can_move_from boolean false
creator object[ezcontentobject] Object
>id string 14
>section_id string 2
>owner_id string 14
>contentclass_id string 4
>name string 'Roberto Kirschbaum'
>is_published string 0
>published string 1033920830
>modified string 1123521782
>current_version string 2
>status string 1
>remote_id string '1bb4fe25487f05527efa8bfd394cecc7'
>current object[ezcontentobjectversion] Object
>versions array Array(2)
>author_array array Array(1)
>class_name string 'User'
>content_class object[ezcontentclass] Object
>contentobject_attributes array Array(5)
>owner object[ezcontentobject] Object
>related_contentobject_array array Array(0)
>related_contentobject_count string 0
>reverse_related_contentobject_array array Array(0)
>reverse_related_contentobject_count string 0
>can_read boolean false
>can_create boolean false
>can_create_class_list array Array(0)
>can_edit boolean false
>can_translate boolean false
>can_remove boolean false
>can_move boolean false
>can_move_from boolean false
>data_map array Array(5)
>main_parent_node_id string 13
>assigned_nodes array Array(1)
>parent_nodes array Array(1)
>main_node_id string 15
>main_node object[ezcontentobjecttreenode] Object
>default_language string 'por-BR'
>content_action_list boolean false
>class_identifier string 'user'
>class_group_id_list array Array(1)
>match_ingroup_id_list boolean false
path array Array(3)
>0 object[ezcontentobjecttreenode] Object
>1 object[ezcontentobjecttreenode] Object
>2 object[ezcontentobjecttreenode] Object
path_array array Array(5)
>0 integer 1
>1 integer 2
>2 integer 121
>3 integer 105
>4 integer 128
parent object[ezcontentobjecttreenode] Object
>node_id string 105
>parent_node_id string 121
>main_node_id string 105
>contentobject_id string 103
>contentobject_version string 4
>contentobject_is_published string 1
>depth string 3
>sort_field string 9
>sort_order string 1
>priority string 0
>modified_subnode string 1124718233
>path_string string '/1/2/121/105/'
>path_identification_string string 'textos/por_autor'
>remote_id string 'e7f8c8f75f71d54f2fb40f5937c85c3f'
>is_hidden string 0
>is_invisible string 0
>name string 'Por Autor'
>data_map array Array(5)
>object object[ezcontentobject] Object
>subtree array Array(5)
>children array Array(5)
>children_count string 5
>contentobject_version_object object[ezcontentobjectversion] Object
>sort_array array Array(1)
>can_read boolean true
>can_create boolean false
>can_edit boolean false
>can_hide boolean false
>can_remove boolean false
>can_move boolean false
>can_move_from boolean false
>creator object[ezcontentobject] Object
>path array Array(2)
>path_array array Array(4)
>parent object[ezcontentobjecttreenode] Object
>url string 'textos/por_autor'
>url_alias string 'textos/por_autor'
>class_identifier string 'folder'
>class_name string 'Folder'
>hidden_invisible_string string '-/-'
>hidden_status_string string 'Visível'
url string 'textos/por_autor/teofilo_braga_joaquim_teofilo_fernandes_braga'
url_alias string 'textos/por_autor/teofilo_braga_joaquim_teofilo_fernandes_braga'
class_identifier string 'autor'
class_name string 'Autor'
hidden_invisible_string string '-/-'
hidden_status_string string 'Visível'

Gabriel Ambuehl

Tuesday 23 August 2005 1:03:31 pm

That is very weird. You can see the reverse relations in the admin GUI right?

Are you 100% sure it's the same content object?

Visit http://triligon.org

Roberto Kirschbaum

Tuesday 23 August 2005 1:20:49 pm

Well, it seems to be the same content object, as when I go to the Admin interface and I look at a Book, and I see:

<i>
Title: Sempre nao (This is the title of the book)
Html: sempre_nao.html (12.70 kB)
Pdf: sempre_nao.pdf (98.69 kB)
Authors: Teófilo Braga
</i>

Authors is an EOR attribute for the book. So when I edited the book, I was able to chose one or more authors from a folder containing authors (a dataclass I made).

I did this in 3 books.

When I tried to see the page for this author, I thought the example code would list the books to which this author is the author... but I get nothing.

Another clue: when I go to the author page in the Admin interface here's the relations window:
/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.

What other places should I look for hints? Maybe the database itself? I have access to it but am not familiar with the tables.

Gabriel Ambuehl

Tuesday 23 August 2005 2:03:23 pm

Mhh, you could look at the ezcontentobject_link table... But if the admin GUI shows the reverse relation, I'd say something else is wrong.

Visit http://triligon.org

Roberto Kirschbaum

Tuesday 23 August 2005 2:19:24 pm

Gabriel,

Yes, it does show. It amazes me! The relations I am trying to portrait are perfectly analogous to the example ones:

coutries ~ companies ==> list all the companies that belong to this country

authors ~ books ==> list all the books that belong to this author

I'll assume something is very wrong indeed and will create new classes to see what happens. For now, thanks for all the attention. If meanwhile you have any insights please let me know.

Roberto

Roberto Kirschbaum

Tuesday 23 August 2005 5:49:54 pm

Hi Gabriel,

I did the following. Just in case my books and authors contentclasses were buggy, I created 2 contentclasses exactly as instructed: coutries and companies. The Companies class has an enhancedobjectrelation pointing to coutry_class objects. And exactly the same happens as described above with the authors/books classes, that is, the example code doesn't work, so when I try to see a country, I don't get to see the related companies.

I looked at the <b>ezcontentobject_link</b> table at the database and <i>it HAS</i> the correct records linking the countries and companies. So I guess some part of the system is forgetting to take a look at this table when it should!!!

On the admin interface, when I look at one coutry, it says:
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.
Sub items [0]
The <Countries_class> class is not configured to contain any sub items.

Still at the admin interface, when I look at one company, it shows the countries it has plants at:
Nome da companhia:
Volks
Countries:
Argentina Brasil United States

However, again:
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.
Sub items [0]

Any ideas??? Could this be a 3.6.1 bug??? Would you like to suggest other table inspections? Maybe look at some filesystem permissions? I'm open to any ideas and willing to help (I'd even provide access to my server)

Roberto Kirschbaum

Tuesday 23 August 2005 6:54:25 pm

An interesting but ugly workaround: somehow I found out that

{$mybooknode.object.data_map.autores.content.id_list|attribute(show)}

shows:

Attribute Type Value
0 string 106
1 string 105
2 string 104
3 string 126

These 106, 105, 104 and 126 are the object_ids of the authors related to the book stored by this node!

As an ugly workaround for my needs, this would make it possible for me, while showing one author, fetch all the books, showing only those which have this authors' object_id in the array I got to show above. This way I could have an "author page" showing an author's picture, bio and links for all of his available works.

But hopefully this adds to the clues we have to make this thing work the ellegant way it was planned to.

Felipe Jaramillo

Tuesday 23 August 2005 9:12:57 pm

Roberto,

It's funny but I had your same problem this morning.

Try this fetch function available in 3.6, it solved it for me:

http://ez.no/doc/ez_publish/technical_manual/3_6/reference/modules/content/fetch_functions/reverse_related_objects

Regards,

Felipe Jaramillo
eZ Certified Extension Developer
http://www.aplyca.com | Bogotá, Colombia

Xavier Dutoit

Wednesday 24 August 2005 3:22:21 am

Hi Roberto,

Could you try to associate the book to the author by hand (ie add the author as a related object on the book object from the admin interface) ?

Can you see it as a related object ?
Can you see the book as a reverse related object on the author ?

Gabriel, what I have in mind it that the reverse related function on the kernel (on 3.6) might avoid the relations when the attribute_id is set (wasn't the case in 3.5.x). Does it make sense ?
In that case, it would mean to patch the kernel so it doesn't exclude the relation when the attribute is set, or use your use/update your operator...

X+

http://www.sydesy.com

Gabriel Ambuehl

Wednesday 24 August 2005 4:35:50 am

Actually, I suggest just using
http://ez.no/doc/ez_publish/technical_manual/3_6/reference/modules/content/fetch_functions/reverse_related_objects
in 3.6. It seems like a much clearer interface and you can actually sort by the attribute that points to us!

Whomever added that, thanks a lot ;)

Visit http://triligon.org

Roberto Kirschbaum

Wednesday 24 August 2005 6:51:05 am

Felipe,

Thanks for the hint! But please read on...

Xavier,

When I did the association by hand, and only then, did the fetch function suggested by Felipe work. Also, only then was I able to see on the admin interface the author as a related object and book as a reverse related object on the author. So I guess you are right about "the reverse related function on the kernel (on 3.6) might avoid the relations when the attribute_id is set (wasn't the case in 3.5.x)" but I wouldn't know how to patch the kernel at my present knowledge level.

So any opinions on what I should do? Should I do the association by hand? Should I wait for a patch?

One last interesting clue: this is how I did make it work, so when accessing an Author's page, I can see links to his books:

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

        {* Fetch all books from Books folder (Folder.node_id=110)*}
        {let books=fetch( content,
                             list,
                             hash( parent_node_id, 110,
                             sort_by, $node.sort_array
                             )
                           )
        }
        {foreach $books as $thisbook}
          {def $authors=$thisbook.object.data_map.authors.content.id_list}
            {foreach $authors as $thisauthor}
              {if eq($thisauthor,$sAuthorId)}
                {* Display a link to the book. *}
                 <a href={concat('/content/view/full/',$thisbook.node_id)|ezurl}>{$thisbook.object.name}</a><BR />
              {/if}
            {/foreach}
          {undef $autores}
        {/foreach}
        {undef}
        </td>