How to getParentId of Gedmo Tree element using symfony3, doctrine2 and stofDoctrineExtensionsBundle - symfony

Introduction
I am using Symfony v3.1.6, Doctrine v2.5.4 and StofDoctrineExtensionsBundle [1] in order to manage Tree structure.
To setup Tree structure I used documentation on Symfony.com [2] followed by documentation on GitHub [3]. Then I proceeded with tree setup - used tree entity from example [4] and used code in [5] to create a tree.
[1] stofDoctrineExtensionsBundle on GitHub;
[2] stofDoctrineExtensinsBundnle documentation on Symfony.com;
[3] Gedmo Tree documentation on GitHub;
[4] Gedmo Tree > Tree Entity example;
[5] Gedmo Tree > Basic Usage Example;
Problem
I want to process parent_id for each element of the tree and I can not figure out how to do it properly.
The Code
controller
/**
* #Route("/tree12", name="tree12")
*/
public function tree12Action(Request $request)
{
$em = $this->getDoctrine()->getManager();
$repo = $em->getRepository('AppBundle:Category');
$rootId = 19;
$query = $em
->createQueryBuilder()
->select('node')
->from('AppBundle:Category', 'node')
->where('node.root = '. $rootId)
->orderBy('node.root, node.lft', 'ASC')
->getQuery();
$build_my_tree = $query->getArrayResult();
$ultra = $this->get('app.ultrahelpers');
$build_my_tree = $ultra->prepareTreeData($build_my_tree);
//var_dump($build_my_tree);
$options = array(
'decorate' => true,
'rootOpen' => '<ul>',
'rootClose' => '</ul>',
'childOpen' => function($node)
{
if (array_key_exists('assigned_root_node', $node))
{
if ($node['assigned_root_node'] === true)
{
return '<li data-jstree=\'{"type":"root"}\'>';
}
}
else if ($node['is_file'] === true)
{
return '<li data-jstree=\'{"type":"file"}\'>';
}
else if ($node['is_file'] === false)
{
if ($node['title'] === 'Saursliezu_dzelzcels')
{
return '<li data-jstree=\'{"type":"home"}\'>';
}
else
{
return '<li data-jstree=\'{"type":"folder"}\'>';
}
}
},
'childClose' => '</li>',
'nodeDecorator' => function($node) use ($repo)
{
dump($node);
if (array_key_exists('assigned_root_node', $node))
{
if ($node['assigned_root_node'] === true)
{
$link_class = 'magenta';
}
//$parent_node_id = $node['parent_id'];
//$parent_node_id = $repo->getParentId($repo->findOneBy(array('id' => $node['id'])));
}
else if ($node['is_file'] === true)
{
$link_class = 'blue';
if ($node['title'] === 'aaa.txt')
{
$link_class = 'red';
}
else if ($node['title'] === 'bbb.txt')
{
$link_class = 'green';
}
//$parent_node_id = $node['parent_id'];
$parent_node_id = $repo->getParentId($repo->findOneBy(array('id' => $node['id'])));
}
else if ($node['is_file'] === false)
{
if ($node['title'] === 'Saursliezu_dzelzcels')
{
$link_class = 'red';
}
else
{
$link_class = 'black';
}
//$parent_node_id = $node['parent_id'];
$parent_node_id = $repo->getParentId($repo->findOneBy(array('id' => $node['id'])));;
}
return '<a data-parent-id="'. $parent_node_id .'" class="'. $link_class .'" href="/project_path/">'. $node['title'] .'</a>';
}
);
$tree = $repo->buildTree($build_my_tree, $options);
var_dump($tree);
return $this->render('tree/tree12_show.html.twig', array('tree' => $tree));
}
Building tree data array
$rootId = 19;
$query = $em
->createQueryBuilder()
->select('node')
->from('AppBundle:Category', 'node')
->where('node.root = '. $rootId)
->orderBy('node.root, node.lft', 'ASC')
->getQuery();
$build_my_tree = $query->getArrayResult();
When I dump $build_my_tree I get:
array (size=6)
0 =>
array (size=7)
'id' => int 1
'title' => string ' Food' (length=10)
'is_file' => boolean false
'lft' => int 1
'lvl' => int 0
'rgt' => int 12
'assigned_root_node' => boolean true
1 =>
array (size=6)
'id' => int 2
'title' => string 'Fruits' (length=6)
'is_file' => boolean false
'lft' => int 2
'lvl' => int 1
'rgt' => int 3
2 =>
array (size=6)
'id' => int 3
'title' => string 'Vegetables' (length=10)
'is_file' => boolean false
'lft' => int 4
'lvl' => int 1
'rgt' => int 11
3 =>
array (size=6)
'id' => int 4
'title' => string 'Carrots' (length=7)
'is_file' => boolean false
'lft' => int 5
'lvl' => int 2
'rgt' => int 6
etc...
But I would like to get the following:
array (size=6)
0 =>
array (size=7)
'id' => int 1
'title' => string ' Food' (length=10)
'is_file' => boolean false
'lft' => int 1
'lvl' => int 0
'rgt' => int 12
'assigned_root_node' => boolean true
'parent_id' => int 0
1 =>
array (size=6)
'id' => int 2
'title' => string 'Fruits' (length=6)
'is_file' => boolean false
'lft' => int 2
'lvl' => int 1
'rgt' => int 3
'parent_id' => int 1
2 =>
array (size=6)
'id' => int 3
'title' => string 'Vegetables' (length=10)
'is_file' => boolean false
'lft' => int 4
'lvl' => int 1
'rgt' => int 11
'parent_id' => int 1
3 =>
array (size=6)
'id' => int 4
'title' => string 'Carrots' (length=7)
'is_file' => boolean false
'lft' => int 5
'lvl' => int 2
'rgt' => int 6
'parent_id' => int 3
etc...
That is parent_id in each tree element.
Conclusion
Please advise.
Thank you for your time and knowledge.

Turns out one has to hint to get all the related values when using getArrayResult.
Vanilla answer [1] did not work for me, so I made little modification (full path to Query).
working code:
$query = $em
->createQueryBuilder()
->select('node')
->from('AppBundle:Category', 'node')
->where('node.root = '. $rootId)
->orderBy('node.root, node.lft', 'ASC')
->getQuery();
$query->setHint(\Doctrine\ORM\Query::HINT_INCLUDE_META_COLUMNS, true);
$build_my_tree = $query->getArrayResult();
Note, that hinting is going on on the $query and is placed between query and getting the result.
Links:
Found initial info here
Documentation on hints

Related

How can I add a filter for specific categories on functions.php?

I am on functions.php and I want to add this filter:
function graphene_alter_the_query( $request ) {
$dummy_query = new WP_Query();
$dummy_query->parse_query( $request );
if (!is_category('25')) {
$request['gdsr_sort'] = 'rating';
}
else {
$request['gdsr_sort'] = 'comment_count';
}
return $request;
}
add_filter( 'request', 'graphene_alter_the_query' );
the filter should do the same thing for all categories except cat 25 but seems like it cant tell it apart like if the IF condition is not detecting the category so I tried to debug it by looking at the values in WP_Query and I get this:
$myquery = new WP_Query(); print_r($myquery);
WP_Query Object ( [query] => Array ( [category_name] => 'my cat' ) [query_vars] => Array ( [category_name] => 'my cat' [error] => [m] => [p] => 0 [post_parent] => [subpost] => [subpost_id] => [attachment] => [attachment_id] => 0 [name] => [pagename] => [page_id] => 0 [second] => [minute] => [hour] => [day] => 0 [monthnum] => 0 [year] => 0 [w] => 0 [tag] => [cat] => [tag_id] => [author] => [author_name] => [feed] => [tb] => [paged] => 0 [meta_key] => [meta_value] => [preview] => [s] => [sentence] => [title] => [fields] => [menu_order] => [embed] => [category__in] => Array ( ) [category__not_in] => Array ( ) [category__and] => Array ( ) [post__in] => Array ( ) [post__not_in] => Array ( ) [post_name__in] => Array ( ) [tag__in] => Array ( ) [tag__not_in] => Array ( ) [tag__and] => Array ( ) [tag_slug__in] => Array ( ) [tag_slug__and] => Array ( ) [post_parent__in] => Array ( ) [post_parent__not_in] => Array ( ) [author__in] => Array ( ) [author__not_in] => Array ( ) ) [tax_query] => WP_Tax_Query Object ( [queries] => Array ( [0] => Array ( [taxonomy] => category [terms] => Array ( [0] => 'my cat' ) [field] => slug [operator] => IN [include_children] => 1 ) ) [relation] => AND [table_aliases:protected] => Array ( ) [queried_terms] => Array ( [category] => Array ( [terms] => Array ( [0] => 'my cat' ) [field] => slug ) ) [primary_table] => [primary_id_column] => ) [meta_query] => [date_query] => [post_count] => 0 [current_post] => -1 [in_the_loop] => [comment_count] => 0 [current_comment] => -1 [found_posts] => 0 [max_num_pages] => 0 [max_num_comment_pages] => 0 [is_single] => [is_preview] => [is_page] => [is_archive] => 1 [is_date] => [is_year] => [is_month] => [is_day] => [is_time] => [is_author] => [is_category] => 1 [is_tag] => [is_tax] => [is_search] => [is_feed] => [is_comment_feed] => [is_trackback] => [is_home] => [is_privacy_policy] => [is_404] => [is_embed] => [is_paged] => [is_admin] => [is_attachment] => [is_singular] => [is_robots] => [is_favicon] => [is_posts_page] => [is_post_type_archive] => [query_vars_hash:WP_Query:private] => 6d85cdf18f3e6a58a470a3002d5807fc [query_vars_changed:WP_Query:private] => [thumbnails_cached] => [stopwords:WP_Query:private] => [compat_fields:WP_Query:private] => Array ( [0] => query_vars_hash [1] => query_vars_changed ) [compat_methods:WP_Query:private] => Array ( [0] => init_query_flags [1] =>
but both tag_id and cat appear empty. Why is that?

How to loop through this data?

I am trying to get the term id from this data returned by get_terms_by()
WP_Term Object ( [term_id] => 29 [name] => gps [slug] => gps [term_group] => 0 [term_taxonomy_id] => 29 [taxonomy] => post_tag [description] => [parent] => 0 [count] => 1 [filter] => raw )
WP_Term Object ( [term_id] => 16 [name] => joystick [slug] => joystick [term_group] => 0 [term_taxonomy_id] => 16 [taxonomy] => post_tag [description] => [parent] => 0 [count] => 3 [filter] => raw )
WP_Term Object ( [term_id] => 14 [name] => lcd [slug] => lcd [term_group] => 0 [term_taxonomy_id] => 14 [taxonomy] => post_tag [description] => [parent] => 0 [count] => 3 [filter] => raw )
but it returns the data in the form of a string
$data = get_term_by('name', $tag , 'post_tag');
print_r($data);
foreach ($data as $tag_id) {
echo $tag_id['term_id'];
}
I want this [term_id] => 29
only term_id
The function get_term_by has a parameter called $output. If you specify it you should get an array back:
$term = get_term_by( 'name', $tag, 'post_tag' );
if ( $term ) {
echo $term->term_id;
}
else {
echo 'Term not found';
}
First of all, you cant get just [term_id] => 291 because you have 3 terms in result, you can have array $term_ids = array(29, 16, 14);
$data = get_term_by('name', $tag , 'post_tag');
$term_ids = array();
foreach ($data as $term) {
$term_ids[] = $term->term_id;
}
print_r($term_ids);

WC_Order does not return the product id by get_items() [duplicate]

This question already has answers here:
Get Order items and WC_Order_Item_Product in WooCommerce 3
(2 answers)
Closed 5 years ago.
I have tried to get the product id and the product name by the following code:
if ( $query->have_posts() ) {
$order_id = $query->posts[0]->ID;
$order = new WC_Order( $order_id );
$items = $order->get_items();
}
foreach ( $items as $item ) {
$product_id = $item['product_id'];
$product = wc_get_product( $item_id );
$product_name = $item['name'];
}
In the above code I got the product name, but the it is return 0 for $product_id. Is there any other method for this?
I can't find any solution for this.
My Edited Version:
When I tried this:
$order_id = $query->posts[0]->ID;
$order = new WC_Order( $order_id );
$items = $order->get_items();
foreach ( $items as $item ) {
$item_id = $item['product_id'];
$product_name = $item['name'];
print_r( $item ); exit;
}
I got this array:
WC_Order_Item_Product Object
(
[extra_data:protected] => Array
(
[product_id] => 0
[variation_id] => 0
[quantity] => 1
[tax_class] =>
[subtotal] => 0
[subtotal_tax] => 0
[total] => 0
[total_tax] => 0
[taxes] => Array
(
[subtotal] => Array
(
)
[total] => Array
(
)
)
)
[data:protected] => Array
(
[order_id] => 684
[name] => Dark Skirt "Erebos" - Large, White
[product_id] => 0
[variation_id] => 0
[quantity] => 1
[tax_class] =>
[subtotal] => 19
[subtotal_tax] => 0
[total] => 19
[total_tax] => 0
[taxes] => Array
(
[total] => Array
(
)
[subtotal] => Array
(
)
)
)
[cache_group:protected] => order-items
[meta_type:protected] => order_item
[object_type:protected] => order_item
[id:protected] => 1
[changes:protected] => Array
(
)
[object_read:protected] => 1
[default_data:protected] => Array
(
[order_id] => 0
[name] =>
[product_id] => 0
[variation_id] => 0
[quantity] => 1
[tax_class] =>
[subtotal] => 0
[subtotal_tax] => 0
[total] => 0
[total_tax] => 0
[taxes] => Array
(
[subtotal] => Array
(
)
[total] => Array
(
)
)
)
[data_store:protected] => WC_Data_Store Object
(
[instance:WC_Data_Store:private] => WC_Order_Item_Product_Data_Store Object
(
[internal_meta_keys:protected] => Array
(
[0] => _order_id
[1] => _name
[2] => _product_id
[3] => _variation_id
[4] => _quantity
[5] => _tax_class
[6] => _subtotal
[7] => _subtotal_tax
[8] => _total
[9] => _total_tax
[10] => _taxes
[11] => _product_id
[12] => _variation_id
[13] => _qty
[14] => _tax_class
[15] => _line_subtotal
[16] => _line_subtotal_tax
[17] => _line_total
[18] => _line_tax
[19] => _line_tax_data
)
[meta_type:protected] => order_item
[object_id_field_for_meta:protected] => order_item_id
)
[stores:WC_Data_Store:private] => Array
(
[coupon] => WC_Coupon_Data_Store_CPT
[customer] => WC_Customer_Data_Store
[customer-download] => WC_Customer_Download_Data_Store
[customer-session] => WC_Customer_Data_Store_Session
[order] => WC_Order_Data_Store_CPT
[order-refund] => WC_Order_Refund_Data_Store_CPT
[order-item] => WC_Order_Item_Data_Store
[order-item-coupon] => WC_Order_Item_Coupon_Data_Store
[order-item-fee] => WC_Order_Item_Fee_Data_Store
[order-item-product] => WC_Order_Item_Product_Data_Store
[order-item-shipping] => WC_Order_Item_Shipping_Data_Store
[order-item-tax] => WC_Order_Item_Tax_Data_Store
[payment-token] => WC_Payment_Token_Data_Store
[product] => WC_Product_Data_Store_CPT
[product-grouped] => WC_Product_Grouped_Data_Store_CPT
[product-variable] => WC_Product_Variable_Data_Store_CPT
[product-variation] => WC_Product_Variation_Data_Store_CPT
[shipping-zone] => WC_Shipping_Zone_Data_Store
)
[current_class_name:WC_Data_Store:private] => WC_Order_Item_Product_Data_Store
[object_type:WC_Data_Store:private] => order-item-product
)
[meta_data:protected] => Array
(
)
)
Of you see the [data:protected] array, you can see this where the [product_id] is 0. That is the problem I guess. But what is the solution for this?
it should be:
foreach ( $items as $item ) {
$product = $item->get_product();
$product_id = $product->get_id();
}

printing all the “maps” related to the content type

my content type, plan to have one or more 'maps'.
With the following php code, I can take all their link:
<?php print render($content['field_mappe_di_riferimento']); ?>
and I get the following result:
I would like to put before the link the image that is within the content type "Mappa", entered in the field "field_immagine_min."
this is the structure of my content type:
this is the content type "Mappa":
with: "print_r($field_mappe_di_riferimento);" I get it:
Array ( [0] => Array ( [nid] => 30 [access] => 1 [node] => stdClass Object ( [vid] => 30 [uid] => 1 [title] => Carta di Marignano, primo giorno, 13 Settembre 1515 [log] => [status] => 1 [comment] => 1 [promote] => 1 [sticky] => 0 [nid] => 30 [type] => mappa [language] => en [created] => 1352066743 [changed] => 1352127342 [tnid] => 0 [translate] => 0 [revision_timestamp] => 1352127342 [revision_uid] => 1 [field_battaglia_di_riferimento] => Array ( [und] => Array ( [0] => Array ( [nid] => 2 ) ) ) [field_immagine_std] => Array ( [und] => Array ( [0] => Array ( [fid] => 23 [alt] => [title] => [width] => 672 [height] => 554 [uid] => 1 [filename] => polesella.jpg [uri] => public://polesella_0.jpg [filemime] => image/jpeg [filesize] => 337755 [status] => 1 [timestamp] => 1352066743 [rdf_mapping] => Array ( ) ) ) ) [field_immagine_min] => Array ( [und] => Array ( [0] => Array ( [fid] => 24 [alt] => [title] => [width] => 150 [height] => 110 [uid] => 1 [filename] => polesella_small.jpg [uri] => public://polesella_small.jpg [filemime] => image/jpeg [filesize] => 10672 [status] => 1 [timestamp] => 1352066743 [rdf_mapping] => Array ( ) ) ) ) [field_testo_opzionale] => Array ( [und] => Array ( [0] => Array ( [value] => pisello [format] => [safe_value] => pisello ) ) ) [rdf_mapping] => Array ( [rdftype] => Array ( [0] => sioc:Item 1 => foaf:Document ) [title] => Array ( [predicates] => Array ( [0] => dc:title ) ) [created] => Array ( [predicates] => Array ( [0] => dc:date 1 => dc:created ) [datatype] => xsd:dateTime [callback] => date_iso8601 ) [changed] => Array ( [predicates] => Array ( [0] => dc:modified ) [datatype] => xsd:dateTime [callback] => date_iso8601 ) [body] => Array ( [predicates] => Array ( [0] => content:encoded ) ) [uid] => Array ( [predicates] => Array ( [0] => sioc:has_creator ) [type] => rel ) [name] => Array ( [predicates] => Array ( [0] => foaf:name ) ) [comment_count] => Array ( [predicates] => Array ( [0] => sioc:num_replies ) [datatype] => xsd:integer ) [last_activity] => Array ( [predicates] => Array ( [0] => sioc:last_activity_date ) [datatype] => xsd:dateTime [callback] => date_iso8601 ) ) [cid] => 0 [last_comment_timestamp] => 1352066743 [last_comment_name] => [last_comment_uid] => 1 [comment_count] => 0 [name] => ant [picture] => 0 [data] => b:0; ) ) )
so I tried to take the nid of the node that I want to take the picture, with success:
print ($content['field_mappe_di_riferimento']['#items'][0][nid]);
I get 30...
I found the solution:
$array = $content['field_mappe_di_riferimento']['#items'];
$k = 0;
foreach($array as $k => $v){
print($k);
//carico il nodo
$node = node_view(node_load($content['field_mappe_di_riferimento']['#items'][$k]['nid']));
//stampa l'img del nodo
print render($node['field_immagine_min']);
}

Getting start and end date of a PHP DatePeriod object?

How can i get the start and end date of a DatePeriod object?
$today = new \DateTime(date('Y-m-d')); // 2012-05-30
$period = new \DatePeriod($today, new \DateInterval('P1M'), 1);
$stats = new UsageStatistics($period);
class UsageStatistics
{
protected $period, $sentEmailCount, $autoSentEmailCount;
public function __construct(\DatePeriod $period)
{
$this->period = $period;
// Current logged in user and email repository
$user = $this->getUser();
$repo = $this->getEmailRepository();
// Get the start and end date for the given period
$startDate = ...
$endDate = ...
$result = $repo->getAllSentCount($user, $startDate, $endDate);
// Assigning object properties
}
public function getSentEmailCount() { return $this->sentEmailCount; }
public function getAutoSentEmailCount() { return $this->autoSentEmailCount; }
}
DatePeriod only implements the Traversable interface and has no other methods to either access elements or retrieve them.
You can do something easy to get start/end dates:
$periodArray = iterator_to_array($period);
$startDate = reset($periodArray);
$endDate = end($periodArray);
I'm using PHP 5.6.9 and it seems that you can use the properties end and start to access your beginning and end DateTime objects:
$p = new DatePeriod($s, $i, $e);
$startTime = $p->start; //returns $s
$endTime = $p->end; //returns $e
The PHP documentation doesn't seem to reflect this. I did a print_r of a DatePeriod object and got the following output:
DatePeriod Object
(
[start] => DateTime Object
(
[date] => 2015-06-01 00:00:00.000000
[timezone_type] => 3
[timezone] => America/Los_Angeles
)
[current] => DateTime Object
(
[date] => 2015-06-08 00:00:00.000000
[timezone_type] => 3
[timezone] => America/Los_Angeles
)
[end] => DateTime Object
(
[date] => 2015-06-08 00:00:00.000000
[timezone_type] => 3
[timezone] => America/Los_Angeles
)
[interval] => DateInterval Object
(
[y] => 0
[m] => 0
[d] => 7
[h] => 0
[i] => 0
[s] => 0
[weekday] => 0
[weekday_behavior] => 0
[first_last_day_of] => 0
[invert] => 0
[days] =>
[special_type] => 0
[special_amount] => 0
[have_weekday_relative] => 0
[have_special_relative] => 0
)
[recurrences] => 1
[include_start_date] => 1
)
It seems that properties current and interval are also visible.
The solution posted by #hakre and #Boby is not correct.
The $endDate is end of the period when PERIOD % INTERVAL = 0.
All other cases $endDate will be END - PERIOD.
$startingDate = new DateTime($startingDay);
$startingDate->modify('previous day');
$startingDate->modify('next Sunday');
$endingDate = new DateTime($endingDay);
$endingDate->modify('next day');
$period = new DatePeriod($startingDate, new DateInterval('P1W'), $endingDate);

Resources