Forum OpenACS Development: new vers of acs_object__name(object_id)

Collapse
Posted by Jim Lynch on
recently, someone altered acs_group__new() so that it would add a row to the lang_messages table with acs-translation.acs_group_1234, and put that string into acs_objects.title so that it would substitute that title.

However, the message column of that row of lang_messages is bland or null or something, and so when you look at the permissions page, the name is blanked out.

This version of acs_object__name looks for that, and if it's found to be blank, it uses other means (the original means) to find the object name.

Incidentally, it should be OK to have a blank message in lang_messages. After thinking about it, I decided that's not a problem I want to solve. Getting the original name back is probably good enough, and if you want group (and other such) names to show up wherever they do, try this.

I'll put the function in the second message in this thread.

-Jim

Collapse
Posted by Jim Lynch on

CREATE OR REPLACE FUNCTION acs_object__name(
   name__object_id integer
) RETURNS varchar AS $$
DECLARE
  object_name            varchar;  
  v_object_id            integer;
  obj_type               record;  
  obj                    record;      
  match_array text[];
  pkg_key text;
  msg_key text;
BEGIN
  -- Find the name function for this object, which is stored in the
  -- name_method column of acs_object_types. Starting with this
  -- object's actual type, traverse the type hierarchy upwards until
  -- a non-null name_method value is found.
  --
  -- select name_method
  --  from acs_object_types
  -- start with object_type = (select object_type
  --                             from acs_objects o
  --                            where o.object_id = name__object_id)
  -- connect by object_type = prior supertype

  select title into object_name
  from acs_objects
  where object_id = name__object_id;

  if (object_name is not null) then
    select regexp_matches(object_name, '^#([^.]*)\.([^.]*)#$') into match_array;

    if NOT FOUND then
      return object_name;
    else
      pkg_key := match_array[1];
      msg_key := match_array[2];

      select
        message into object_name
      from
        lang_messages
      where
        package_key = pkg_key
       and
        message_key = msg_key;

      if FOUND then
        if object_name is not NULL and object_name <> '' then
          return object_name;
        end if;
      end if;
    end if;
  end if;

  for obj_type
  in select o2.name_method
        from acs_object_types o1, acs_object_types o2
       where o1.object_type = (select object_type
                                 from acs_objects o
                                where o.object_id = name__object_id)
         and o1.tree_sortkey between o2.tree_sortkey and tree_right(o2.tree_sortkey)
    order by o2.tree_sortkey desc
  loop
   if obj_type.name_method != '' and obj_type.name_method is NOT null then

    -- Execute the first name_method we find (since we're traversing
    -- up the type hierarchy from the object's exact type) using
    -- Native Dynamic SQL, to ascertain the name of this object.
    --
    --execute 'select ' || object_type.name_method || '(:1) from dual'

    for obj in execute 'select ' || obj_type.name_method || '(' || name__object_id || ')::varchar as object_name' loop
        object_name := obj.object_name;
        exit;
    end loop;

    exit;
   end if;
  end loop;

  return object_name;
  
END;
$$ LANGUAGE plpgsql stable strict;

Collapse
Posted by Jim Lynch on

found another way a blank name could get returned... say the very first query found acs_objects.title not nul but equal to ''... in that case the regexp_matches fails, FOUND is false, and it gets returned right there...

So the first if, which now reads:

  if (object_name is not null) then
should read:
  if (object_name is not null and object_name <> '') then
and then, this part will no longer be able to return a blank name.

-Jim

Collapse
Posted by Gustaf Neumann on
jim,

where have you found this version of acs_object__name()? AFIKT, it is not in any of the recent versions of OpenACS. The part with the regular expressions looks strange to me. The current version can be viewed the easiest on [1]

-g

[1] https://github.com/openacs/openacs-core/blob/master/packages/acs-kernel/sql/postgresql/acs-objects-create.sql#L1010

Collapse
Posted by Jim Lynch on
where have you found this version of acs_object__name()?

I took a copy of acs_object__name(obj_id) and I altered it myself.

The current version ends up with a blank name if acs_objects.title contains <span>#</span>foo.bar# and message foo.bar in lang_messages is blank or null.

The regex looks for "<span>#</span>pkg_key.msg_key#" and splits the keys so I can query for it, and test for blank/nullness, with the idea being, if that turns out to be blank or null, it's probably not the name we want. If that's the case, I let the existing code get the name by the method that was already there, I didn't change any of that.

-Jim

Collapse
Posted by Jim Lynch on
If you want justification for at least trying it, I'll contend that my addition isn't all that intrusive... the only way it "wakes up" is if acs_objects.title is non blank, and only then if the title follows the form "<span>#</span>pkg_key.msg_key#".

If the query after that finds there IS something in the message, that text is used as the object name, so I'm letting the original developer finish his work... or not, and either way, aca_object__name() (well, my version) tries a little harder to come up with a nonblank object name. If someone changes group__new() so that it puts the group name in the lang_messages table, my code will use that name.

The only way acs_object__name() can lose now, is if there does not exist a name method for the object type (or for any supertypes), or the name method itself returns blank.

-Jim

Collapse
Posted by Gustaf Neumann on
i am still confused, what the intention of your posting is: are you reporting a bug or do you want to discuss some extensions? What does "Recently, someone altered acs_group__new() so that it would add a row to the lang_messages table" refer to? Please be more precise.

If "title" in acs_objects is not specified, it should be NULL, if it is specified as the empty string, then it should be ''.

Collapse
Posted by Jim Lynch on
Gustaf,

This is a bug report with a suggested fix. The bug is, acs_object__name() returns a string from acs_objecs.title that looks like (pound sign)acs-translations.group_title_2702(pound sign), which gets looked up. The value it returns (from the table lang_messages) is blank, so that's what the old version of acs_object__name() returns. The "Recently..." comment refers to that change, which may not be complete.

To shed light on the problem, try this:

  • Create an application_group,
  • Find its object_id,
  • In psql, run: select title from acs_objects where object_id = theGroupId;
  • Still in psql, run: select acs_object__name(theGroupID);
  • Still psql, run select message from lang_messages where psckage_key = 'acs-translations' and message_key = 'group_title_(theGroupID)';
  • You should notice that the result of this query is either blank or null, and is why blank is displayed when group names are displayed.
My intent for my change to acs_object__name() is to fix the blank-group-name problem and be sufficiently nonintrusive so that (1) I'm avoiding interfering with the developer who started this change, and (2) acs_object__name() should work whether he completes his work or not.

-Jim

Collapse
Posted by Gustaf Neumann on
Jim,

the best place for bug reports is the bug tracker. The result below looks ok to me.

Do you get different results for acs_object__name()? I still don't see the connection with acs-translations.

-g

openacs.org=# select object_id, title from acs_objects where object_type = 'application_group';
 object_id |           title            
-----------+----------------------------
      3830 | Main Site Parties
     44322 | OpenACS Parties
     46079 | demo Parties
     46194 | Test Subsite Parties
     46238 | Projects Parties
     46273 | OpenACS Subsite Parties
     47519 | dotWRK Parties
     57366 | dotLRN Parties
    128847 | OpenACS Governance Parties
    179469 | CVS Committers
(10 rows)

openacs.org=# select acs_object__name(3830);
 acs_object__name  
-------------------
 Main Site Parties
(1 row)

openacs.org=# select message from lang_messages where package_key = 'acs-translations';
 message 
---------
(0 rows)
Collapse
Posted by Jim Lynch on
Gustaf,

You're right, the titles look good, and, those groups have been around on openacs.org ro maybe 10 or 20 years.

What do you find on a group created today or so?

-Jim

Collapse
Posted by Gustaf Neumann on
Applications groups created today don't look different. Today in ds/shell:
application_group::new -group_name foo
in psql
openacs.org=# select object_id, title, creation_date from acs_objects where object_type = 'application_group';
 object_id |           title            |         creation_date         
-----------+----------------------------+-------------------------------
      3830 | Main Site Parties          | 2002-07-11 22:08:20+02
     44322 | OpenACS Parties            | 2002-08-12 21:20:32+02
     46079 | demo Parties               | 2002-08-13 20:47:17+02
     46194 | Test Subsite Parties       | 2002-08-20 21:44:29+02
     46238 | Projects Parties           | 2002-08-20 21:48:27+02
     46273 | OpenACS Subsite Parties    | 2002-08-20 21:52:09+02
     47519 | dotWRK Parties             | 2002-09-23 23:10:55+02
     57366 | dotLRN Parties             | 2002-10-31 17:21:02+01
    128847 | OpenACS Governance Parties | 2003-09-28 20:15:03.255242+02
    179469 | CVS Committers             | 2004-05-04 10:52:55.872763+02
   4216650 | foo                        | 2015-01-02 09:06:42.58954+01
(11 rows)

openacs.org=# select acs_object__name(4216650);
 acs_object__name 
------------------
 foo
(1 row)
Do you get different results?

-g

Collapse
Posted by Jim Lynch on
sorry for delay... I have some results to show you, but first do you happen to know the &#...; for #?

-Jim


Collapse
Posted by Benjamin Brink on
stackoverflow.com/questions/3025171/whats-the-html-character-entity-for-the-sign
Collapse
Posted by Jim Lynch on

Hi, here are the results...

using this query:


        select 
            o.object_type, 
            o.creation_date::date, 
            o.title
        from 
            acs_objects o,
            lang_messages m,
            (select object_id, regexp_matches(title, '#([^.#]*).([^.#]*)#') as matcha from acs_objects) r
        where 
            o.object_id = r.object_id
          and
            r.matcha[1] = m.package_key
          and
            r.matcha[2] = m.message_key
          and
            (m.message is null or m.message = '')
        order by 
            o.title;
I get:

    object_type    | creation_date |                title                
-------------------+---------------+-------------------------------------
 application_group | 2014-02-05    | #acs-translations.group_title_1727#
 application_group | 2014-02-23    | #acs-translations.group_title_1958#
 application_group | 2014-12-22    | #acs-translations.group_title_2702#
(3 rows)
without the \ char at the start of the title field.

Collapse
Posted by Jim Lynch on
without the r and lang_message NULL or '', I get 70 rows.
Collapse
Posted by Jim Lynch on
As far as intent for posting, yes, this is a bug report (with suggested fix), and I'm also totally willing to discuss this way potentially other ways to solve it.

-Jim

Collapse
Posted by Jim Lynch on
Oh yeah happy new year
Collapse
Posted by Gustaf Neumann on
actually, there is a bug in application_group::delete, the group can't be deleted via the api due to a fk violation. i will fix this soon.
Collapse
Posted by Jim Lynch on
I'll look at it in a bit
Collapse
Posted by Gustaf Neumann on
The bug in application_group::delete is fixed in the oacs-5-8-branch since jan 2.
Not sure, i understand "&#...; for #".
Collapse
Posted by Jim Lynch on
I got the # part from the stackoverflow article.

Are you still committing to cvs, or have we switched to git?

Could you show a link to the commit either way?

-Jim