Author
|
Message
|
Luis Micunco
|
Tuesday 05 May 2009 2:04:16 am
Hi, I know this topic is repeated, but i havent found a solution. Quoting from the fetch function list documentation:
"It is not possible to filter on attributes of different classes, for example it is not possible to filter on both "article/show_comments" and "folder/show_comments" in the same filter. "
Isnt there an good way to achieve this yet?. Im in a situation where i need to do a fetch from a php function to get objects from 2 different classes, like: "images, maps". those classes has a common "selection" attribute called: "category" . I tried this:
$fetchParams = array(
'ClassFilterType' => 'include',
'ClassFilterArray' => array(30, 54) ,
'AttributeFilter' => array( 'or',
array(342, "=", 3),
array(531, "=", 3 )
) );
$result = eZContentObjectTreeNode::subTreeCountByNodeID( $fetchParams, 221 );
The fetch returns in no results, but works fine by removing the statement.
array(531, "=", 3 )
Thank you.
|
Ivo Lukac
|
Tuesday 05 May 2009 2:22:16 am
Hello, You can do this only using custom extended attribute filter. I will try to find an example and post it here
http://www.linkedin.com/in/ivolukac
http://www.netgen.hr/eng/blog
http://twitter.com/ilukac
|
Ivo Lukac
|
Tuesday 05 May 2009 2:38:35 am
Found something for ez3 (php4). If you working with ez4 (php5) you will need to modify the constructor call. This filter is used for objectrelation attribute, but you can make it to work with selection attribute. Make a new extension with file kernel\classes\ezcategoryfilter.php
<?php
class eZExtendedCategoryFilter
{
/*! Constructor */
function eZExtendedCategoryFilter()
{
}
function createSqlParts( $params )
{
$result = array( 'tables' => '', 'joins' => '' );
if ( isset( $params['classes'] ) )
{
$classes = $params['classes'];
} else
return;
$filterSQL = array();
$filterSQL['from'] = ", ezcontentobject_link i1 ";
$attribute_ids = array();
foreach ($classes as $class) {
array_push($attribute_ids,eZContentObjectTreeNode::classAttributeIDByIdentifier( $class . '/category' ));
}
$class_cond = array();
foreach ($attribute_ids as $aid) {
if ($aid) {
array_push($class_cond, 'i1.contentclassattribute_id = '.$aid);
}
}
$string_class_cond = implode(" OR ",$class_cond);
$filterSQL['where'] = " ( i1.from_contentobject_id = ezcontentobject.id AND (" . $string_class_cond . ") AND i1.from_contentobject_version = ezcontentobject.current_version AND i1.to_contentobject_id = " . $params['object_id'] . ") AND ";
return array( 'tables' => $filterSQL['from'], 'joins' => $filterSQL['where'] );
}
}
?>
Also add this to extendedattributefilter.ini:
[ExtendedCategoryFilter]
#The name of the extension where the filtering code is defined.
ExtensionName=your_extension
#The name of the filter class.
ClassName=eZExtendedCategoryFilter
#The name of the method which is called to generate the SQL parts.
MethodName=createSqlParts
#The file which should be included (extension/myextension will automatically be prepended).
FileName=kernel/classes/ezcategoryfilter.php
And activate the extension. You then use this in your templates like this:
fetch( 'content', 'tree', hash( parent_node_id, $parent_node_id ,
'extended_attribute_filter', hash('id','ExtendedCategoryFilter','params',hash('object_id', $value,'classes',array('class1','class2'))), ))}
http://www.linkedin.com/in/ivolukac
http://www.netgen.hr/eng/blog
http://twitter.com/ilukac
|
Luis Micunco
|
Tuesday 05 May 2009 3:22:06 am
Hi. I will give it a try. Thanks a lot.
|
Luis Micunco
|
Friday 08 May 2009 1:39:11 am
Hi.
Now i got it to work. But what about the "sort by". I need also to "sort" the result by a "date" attribute. Again its is a common attribute in both classes with the same identifier.
Is it possible to include an "ORDER BY" o something similiar in the code ?. Thank you. I will post my result code later.
|
Ivo Lukac
|
Friday 08 May 2009 1:56:09 am
In extended attribute filter you are attaching some SQL parts to ez query so you probably can add your 'order by'
http://www.linkedin.com/in/ivolukac
http://www.netgen.hr/eng/blog
http://twitter.com/ilukac
|
Luis Micunco
|
Friday 08 May 2009 2:01:08 am
Yes.
I think there is a default "ORDER BY" value. Looking at the MYSQL DEBUG of my fetch, it appends: "ORDER BY path_string ASC" Any idea? Thank you
|
Ivo Lukac
|
Friday 08 May 2009 3:37:58 am
Hm, just checked some code, and it seems it can't be done. createSqlParts function returns 'tables' and 'joins' and that's it. There is no extended sorting :(
http://www.linkedin.com/in/ivolukac
http://www.netgen.hr/eng/blog
http://twitter.com/ilukac
|
Peter Halasz
|
Monday 11 May 2009 1:37:16 am
Actually you can return columns as well. The docs don't say it but you can have a colums part for the return array, then you can have the ORDER BY to order by that custom column as well. Check this for clarification http://pubsvn.ez.no/doxygen/4.0/html/ezcontentobjecttreenode_8php-source.html#l00870
|
Ivo Lukac
|
Monday 11 May 2009 3:16:39 am
You mean like sending with columns variable additional attribute with AS FOOBAR, and then in fetch sort it with 'FOOBAR'? Hm, could work, but I don't have time to experiment :/
http://www.linkedin.com/in/ivolukac
http://www.netgen.hr/eng/blog
http://twitter.com/ilukac
|
Peter Halasz
|
Tuesday 12 May 2009 3:53:48 pm
Yup exactly :)
|
Luis Micunco
|
Wednesday 13 May 2009 10:19:11 am
Hi there again. This worked for the sorting:
fetch( 'content', 'tree', hash( parent_node_id, $parent_node_id ,
'sort_by', array(array('i1.sort_key_int', 0)),
'extended_attribute_filter', hash('id','ExtendedCategoryFilter','params',hash('object_id', $value,'classes',array('class1','class2'))), ))}
I think this is because "i1" is the "ezcontentobject_attribute" alias, and "sort_key_int" the "ezcontentobject_attribute" field im sorting by.
I will post the entire code then- Thanks to all
|
Benjamin Lorteau
|
Saturday 23 May 2009 3:44:57 am
Hey Luis, I just stumble upon the very same problem as you, and it seems that you found your way through. Could you share your solution ? Thanks in advance ! Benjamin
eZ Publish personal project : http://www.aeriesguard.com [fr]
|
Clemens T
|
Wednesday 29 July 2009 6:25:20 am
Benjamin, and others, Maybe I'm too late, but here's my extende PHP filter. First off, important to know is that I have multiple classes that share a category string. A dropdown box in my case is used to filter through these categories, hence the 'LIKE' statement (categories can be added just by typing text and separating by comma's). Here's my code (based on previous steps discussed in this thread):
<?php
class eZExtendedCategoryFilter
{
/*! Constructor */
function eZExtendedCategoryFilter()
{
}
function createSqlParts( $params )
{
$result = array( 'tables' => '', 'joins' => '' );
if ( isset( $params['classes'] ) )
{
$classes = $params['classes'];
}
else
return;
$filterSQL = array();
$filterSQL['from'] = ", ezcontentobject_attribute ";
$attribute_ids = array();
foreach ($classes as $class) {
array_push($attribute_ids,eZContentObjectTreeNode::classAttributeIDByIdentifier( $class . '/categories' ));
}
$class_cond = array();
foreach ($attribute_ids as $aid)
{
if ($aid)
{
array_push($class_cond, 'ezcontentobject_attribute.contentclassattribute_id = '.$aid);
}
}
$string_class_cond = implode(" OR ",$class_cond);
$filterSQL['where'] = " ( ezcontentobject_attribute.contentobject_id = ezcontentobject.id AND (" .
$string_class_cond .
") AND ezcontentobject_attribute.version = ezcontentobject.current_version "
." AND ezcontentobject_attribute.data_text LIKE '%" .
$params['textLIKEfilter'] .
"%') AND ";
return array( 'tables' => $filterSQL['from'], 'joins' => $filterSQL['where'] );
}
}
?>
And the template function looks like this:
{def $list=fetch('content','list',hash('parent_node_id',$myNodeID,
offset, $#view_parameters.offset,
sort_by, array( 'priority', false()),
limit, 5,
'extended_attribute_filter', hash('id','ExtendedCategoryFilter',
'params',
hash( 'textLIKEfilter', ezhttp('categories', 'get'),
'classes',array('class1','class2')
)
)
))}
Hopefully this helps you, and others.
|
Benjamin Lorteau
|
Wednesday 29 July 2009 6:42:21 am
Hey Clemens, thanks for you filter, which seems to open an interesting way to filter on multiple classes. I should use it one way or another next time I stumble upon the same problem. Oh, and by the way, you shouldn't use ezhttp operator in your template if it's a view template, use View Parameters instead ;-)
eZ Publish personal project : http://www.aeriesguard.com [fr]
|
quang lam
|
Friday 21 January 2011 3:22:00 am
Hi I was only interested by sorting on different attributes in differents classes within a fetch Base on previous posts, I was able to correct the code ( EZ v 4.x) in this purpose :
<?php
class eZExtendedCategoryFilter
{
/*! Constructor */
function eZExtendedCategoryFilter()
{
}
function createSqlParts( $params )
{
$result = array( 'tables' => '', 'joins' => '' );
if ( isset( $params['classes'] ) )
{
$classes = $params['classes'];
} else
return;
if ( isset( $params['sort_fields'] ) )
{
$sort_fields = $params['sort_fields'];
} else
return;
$filterSQL = array();
$filterSQL['from'] = ", ezcontentobject_attribute ";
$attribute_ids = array();
$i=0;
foreach ($classes as $class) {
array_push($attribute_ids,eZContentObjectTreeNode::classAttributeIDByIdentifier( $class . '/'.$sort_fields[$i] ));
$i++;
}
$class_cond = array();
foreach ($attribute_ids as $aid) {
if ($aid) {
array_push($class_cond, 'ezcontentobject_attribute.contentclassattribute_id = '.$aid);
}
}
$string_class_cond = implode(" OR ",$class_cond);
$filterSQL['where'] = " ( ezcontentobject_attribute.contentobject_id = ezcontentobject.id AND (" . $string_class_cond . ") AND ezcontentobject_attribute.version = ezcontentobject.current_version ". ") AND ";
return array( 'tables' => $filterSQL['from'], 'joins' => $filterSQL['where'] );
}
}
?> Template call
{def $news=fetch( 'content', 'tree', hash( parent_node_id, $parent_node_id ,
'limit',$nbnews,
'sort_by', array(array('ezcontentobject_attribute.data_int', 0)),
'extended_attribute_filter', hash('id','ExtendedCategoryFilter','params',hash('classes',array('press','article_mainpage'),'sort_fields',array('date','publish_date')))
))
- sort_by : put the data type of the attributes. i.e my attributes were date. they are store as data_int en EZ
-
params :
classes : put the class names ,
sort_fields: put the user defined identifiers on which the sort should run, in the same order as class names. i.e . I have two classes ( press - field identifier : date / article_mainpage - field identifier : publish_date )
Thanks everyone for helping me to write this "missing" feature
|
gilles guirand
|
Sunday 23 January 2011 1:10:19 pm
And also, you could use eZ Find :
{def $search=fetch( ezfind, search,
hash( query , '',
'class_id', array('press','article_mainpage'),
'limit', 10,
'sort_by', hash('attr_date_dt', 'desc')
))}
--
Gilles Guirand
eZ Community Board Member
http://twitter.com/gandbox
http://www.gandbox.fr
|