Fetch nodes NOT in a given language

Author Message

Hugues Charleux

Friday 10 December 2010 6:52:26 am

Hi eZ Community.

I am building a friendly UI in administration for redactors to see which objects have not yet been translated in a given language / subtree.

To do so I want to fetch all objects in the subtree that have no xxx-YY language version.

I can't find a way to achieve this with eZContentObjectTreeNode::subTreeByNodeID() params :

Language related SQL conditions are generated by default, so I think even an extendedAttributeFilter won't do the job.

I think I am going to try to achieve this with a "hand made" SQL Query to get nodes ids and then fetch them individually but that looks awfull...

Does any one has a another lead ?

Hugues Charleux

Friday 10 December 2010 8:52:38 am

Ok for the record this is how I finally did it :

/*.... */
$parentNodeID = 42;
$language     = 'eng-GB';

/* Fetch parent node to get the path string */
$parentNode = eZContentObjectTreeNode::fetch( $parentNodeID, false, false );

/*
 Get the node ids
 Query relying on ezcontentobject_name.real_translation with crappy IN( SELECT... ) statement 
 to avoid playing with language_mask (too many combinations)
*/
$sql = 'SELECT t.node_id FROM ezcontentobject_tree t, ezcontentclass c, ezcontentobject o 
WHERE 
    c.identifier NOT IN("'. implode('", "', $excludeClasses ).'" )
AND c.id = o.contentclass_id        
AND o.id = t.contentobject_id    
AND t.node_id = t.main_node_id    
AND t.path_string like "'.$parentNode['path_string'].'%"    
AND o.id NOT IN( 
      SELECT contentobject_id FROM ezcontentobject_name WHERE real_translation = "'.$language.'"
    )
    ';

$db = eZDB::instance();
$result = $db->arrayQuery( $sql );

$nodeIDs = array();
foreach( $result as $row )
{
    $nodeIDs[] = $row['node_id'];
}

/* Retrieves eZContentObjectTreeNode objects */
$nodes = eZContentObjectTreeNode::fetch( $nodeIDs );

/*....*/

This will get you all main nodes for objects that don't have an english version under the node whose id is 42.

Nicolas Pastorino

Friday 10 December 2010 9:11:43 am

Hi Hugues, and thanks for sharing the solution,

From the top of my head and without having at hand, right now another solution, i can only tell that this

...
AND o.id NOT IN(       
   SELECT contentobject_id FROM ezcontentobject_name WHERE real_translation = "'.$language.'"    )    
';

can be of an issue in case of a large content base, perf-wise.

--
Nicolas Pastorino
Director Community - eZ
Member of the Community Project Board

eZ Publish Community on twitter: http://twitter.com/ezcommunity

t : http://twitter.com/jeanvoye
G+ : http://plus.tl/jeanvoye

Hugues Charleux

Friday 10 December 2010 9:30:31 am

"

Hi Hugues, and thanks for sharing the solution,

From the top of my head and without having at hand, right now another solution, i can only tell that this

...
AND o.id NOT IN(       
   SELECT contentobject_id FROM ezcontentobject_name WHERE real_translation = "'.$language.'"    )    
';

can be of an issue in case of a large content base, perf-wise.

"

Exactly ! I should have warn about this potential issue

I was convinced there was a way to make a SQL query that gets records not matching a join but can't figure out how to do this with MySQL.

It's runing fine so far with about 22 000 record in ezcontentobject_name

Another point about ezcontentobject_name's real_translation and content_translation fields : Those two fields looks like storing the same data so I just took one of them... Not a very scientific approach I admit.

mysql> SELECT COUNT(*) FROM ezcontentobject_name WHERE content_translation != real_translation ;
+----------+
| COUNT(*) |
+----------+
| 0 |
+----------+

Nicolas Pastorino

Friday 10 December 2010 9:59:46 am

Why not joining on the ezcontentobject_name table ?

SELECT t.node_id FROM ezcontentobject_tree t, ezcontentclass c, ezcontentobject o, ezcontentobject_name oname 
WHERE c.identifier NOT IN("'. implode('", "', $excludeClasses ).'" )
AND c.id = o.contentclass_id        
AND o.id = t.contentobject_id    
AND t.contentobject_id = oname.contentobject_id
AND t.node_id = t.main_node_id    
AND t.path_string like "'.$parentNode['path_string'].'%"    
AND oname.real_translation != "'.$language.'"

--
Nicolas Pastorino
Director Community - eZ
Member of the Community Project Board

eZ Publish Community on twitter: http://twitter.com/ezcommunity

t : http://twitter.com/jeanvoye
G+ : http://plus.tl/jeanvoye

Hugues Charleux

Friday 10 December 2010 1:51:26 pm

With this one objects with another locale than $language will be returned, but even if they also have a $language version.

Hugues Charleux

Tuesday 14 December 2010 6:55:57 am

Ok here is the right way to query, using this time the language mask and no mass destruction sub select.

<span>/*.... */</span> <span>$parentNodeID</span> <span>=</span> <span>42</span><span>;</span> <span>$language</span>     <span>=</span> <span>'eng-GB'</span><span>;
// Get the language object to have its ID.
</span>$oLang = eZContentLanguage::fetchByLocale( $language );   <span>/* Fetch parent node to get the path string */</span> <span>$parentNode</span> <span>=</span> eZContentObjectTreeNode<span>::</span><span>fetch</span><span>(</span> <span>$parentNodeID</span><span>,</span> <span>false</span><span>,</span> <span>false</span> <span>)</span><span>;</span>   <span>/*  Get the node ids */</span> <span>$sql</span> <span>=</span> <span>'SELECT t.node_id FROM ezcontentobject_tree t, ezcontentclass c, ezcontentobject o  WHERE      c.identifier NOT IN("'</span><span>.</span> <a href="http://www.php.net/implode" target="ez_no_documentation"><span>implode</span></a><span>(</span><span>'", "'</span><span>,</span> <span>$excludeClasses</span> <span>)</span><span>.</span><span>'" ) AND c.id = o.contentclass_id         AND o.id = t.contentobject_id     AND t.node_id = t.main_node_id     AND t.path_string like "'</span><span>.</span><span>$parentNode</span><span>[</span><span>'path_string'</span><span>]</span><span>.</span><span>'%"     AND NOT ( o.language_mask & '. $oLang->ID .' ) </span><span>'</span><span>;</span>   <span>$db</span> <span>=</span> eZDB<span>::</span><span>instance</span><span>(</span><span>)</span><span>;</span> <span>$result</span> <span>=</span> <span>$db</span><span>-></span><span>arrayQuery</span><span>(</span> <span>$sql</span> <span>)</span><span>;</span>   <span>$nodeIDs</span> <span>=</span> <a href="http://www.php.net/array" target="ez_no_documentation"><span>array</span></a><span>(</span><span>)</span><span>;</span> <span>foreach</span><span>(</span> <span>$result</span> <span>as</span> <span>$row</span> <span>)</span> <span>{</span>     <span>$nodeIDs</span><span>[</span><span>]</span> <span>=</span> <span>$row</span><span>[</span><span>'node_id'</span><span>]</span><span>;</span> <span>}</span>   <span>/* Retrieves eZContentObjectTreeNode objects */</span> <span>$nodes</span> <span>=</span> eZContentObjectTreeNode<span>::</span><span>fetch</span><span>(</span> <span>$nodeIDs</span> <span>)</span><span>;</span>   <span>/*....*/</span>

Powered by eZ Publish™ CMS Open Source Web Content Management. Copyright © 1999-2014 eZ Systems AS (except where otherwise noted). All rights reserved.

eZ debug

Timing: Jan 29 2025 23:52:46
Script start
Timing: Jan 29 2025 23:52:46
Module start 'layout'
Timing: Jan 29 2025 23:52:46
Module start 'content'
Timing: Jan 29 2025 23:52:46
Module end 'content'
Timing: Jan 29 2025 23:52:46
Script end

Main resources:

Total runtime0.9404 sec
Peak memory usage4,096.0000 KB
Database Queries70

Timing points:

CheckpointStart (sec)Duration (sec)Memory at start (KB)Memory used (KB)
Script start 0.00000.0050 588.1563151.2109
Module start 'layout' 0.00500.0030 739.367236.6563
Module start 'content' 0.00800.9317 776.0234560.7188
Module end 'content' 0.93970.0007 1,336.742223.8438
Script end 0.9404  1,360.5859 

Time accumulators:

 Accumulator Duration (sec) Duration (%) Count Average (sec)
Ini load
Load cache0.00290.3132160.0002
Check MTime0.00120.1280160.0001
Mysql Total
Database connection0.00060.067410.0006
Mysqli_queries0.887094.3238700.0127
Looping result0.00050.0567680.0000
Template Total0.896195.320.4481
Template load0.00220.237220.0011
Template processing0.893995.048420.4469
Template load and register function0.00020.018510.0002
states
state_id_array0.00210.220110.0021
state_identifier_array0.00130.142320.0007
Override
Cache load0.00190.1979510.0000
Sytem overhead
Fetch class attribute can translate value0.00060.062620.0003
Fetch class attribute name0.00090.095090.0001
XML
Image XML parsing0.00210.223120.0010
class_abstraction
Instantiating content class attribute0.00000.0025140.0000
General
dbfile0.00280.2933220.0001
String conversion0.00000.000640.0000
Note: percentages do not add up to 100% because some accumulators overlap

Templates used to render the page:

UsageRequested templateTemplateTemplate loadedEditOverride
1node/view/full.tplfull/forum_topic.tplextension/sevenx/design/simple/override/templates/full/forum_topic.tplEdit templateOverride template
7content/datatype/view/ezimage.tpl<No override>extension/sevenx/design/simple/templates/content/datatype/view/ezimage.tplEdit templateOverride template
7content/datatype/view/ezxmltext.tpl<No override>extension/community_design/design/suncana/templates/content/datatype/view/ezxmltext.tplEdit templateOverride template
13content/datatype/view/ezxmltags/paragraph.tpl<No override>extension/ezwebin/design/ezwebin/templates/content/datatype/view/ezxmltags/paragraph.tplEdit templateOverride template
1content/datatype/view/ezxmltags/link.tpl<No override>design/standard/templates/content/datatype/view/ezxmltags/link.tplEdit templateOverride template
5content/datatype/view/ezxmltags/literal.tpl<No override>extension/community/design/standard/templates/content/datatype/view/ezxmltags/literal.tplEdit templateOverride template
1content/datatype/view/ezxmltags/quote.tpldatatype/ezxmltext/quote.tplextension/ezwebin/design/ezwebin/override/templates/datatype/ezxmltext/quote.tplEdit templateOverride template
1content/datatype/view/ezxmltags/line.tpl<No override>design/standard/templates/content/datatype/view/ezxmltags/line.tplEdit templateOverride template
1print_pagelayout.tpl<No override>extension/community/design/community/templates/print_pagelayout.tplEdit templateOverride template
 Number of times templates used: 37
 Number of unique templates used: 9

Time used to render debug report: 0.0001 secs