doctrine2 get rows from mapping table - doctrine-orm

I am trying to get the mapping table associated ids.
mapping_table
id service_receiver_id service_provider_id
1 1 2
2 4 1
How can i write the doctrine query for retrieving 1 mapped to...
i need the results like,
associated_with
2
4
In my case i have using this query:
$qb->select('om', 'o', 'ot')
->from('Organization\Entity\OrgMapping', 'om')
->leftJoin('om.organization', 'o')
->where('om.organization = :hspId')
->setParameter('hspId', $hspId);
above query result only
//List of Associates that is Mapped Already
$organizations = $this->orgMappingRepository->listAssociatesByHSPId($hspId, $mapType, $filterBy, $searchBy, $pageNo, $paginationArr);
$mappedAssociates = array();
foreach ($organizations as $org) {
$mappedAssociates[$org->getServiceProvider()->getId()] = array(
'id' => $org->getServiceProvider()->getId(),
'name' => $org->getServiceProvider()->getName(),
'orgType' => $org->getServiceProvider()->getOrgType()->getName(),
'logo' => $org->getServiceProvider()->getLogo(),
'cityName' => $org->getServiceProvider()->getCity() ? $org->getServiceProvider()->getCity()->getName() : null,
'areaName' => $org->getServiceProvider()->getArea() ? $org->getServiceProvider()->getArea()->getName() : null,
'zipcode' => $org->getServiceProvider()->getZipcode(),
);
}
the result i am getting is :
id service_receiver_id service_provider_id
1 1 2

Related

How to extract where clause as array in spark sql?

I am trying to extract where clause from SQL query.
Multiple conditions in where clause should be in form array. Please help me.
Sample Input String:
select * from table where col1=1 and (col2 between 1 and 10 or col2 between 190 and 200) and col2 is not null
Output Expected:
Array("col1=1", "(col2 between 1 and 10 or col2 between 190 and 200)", "col2 is not null")
Thanks in advance.
EDIT:
My question here is like... I would like to split all the conditions as separate items... let's say my query is like
select * from table where col1=1 and (col2 between 1 and 10 or col2 between 190 and 200) and col2 is not null
The output I'm expecting is like
List("col1=1", "col2 between 1 and 10", "col2 between 190 and 200", "col2 is not null")
The thing is the query may have multiple levels of conditions like
select * from table where col1=1 and (col2 =2 or(col3 between 1 and 10 or col3 is between 190 and 200)) and col4='xyz'
in output each condition should be a separate item
List("col1=1","col2=2", "col3 between 1 and 10", "col3 between 190 and 200", "col4='xyz'")
I wouldn't use Regex for this. Here's an alternative way to extract your conditions based on Catalyst's Logical Plan :
val plan = df.queryExecution.logical
val predicates: Seq[Expression] = plan.children.collect{case f: Filter =>
f.condition.productIterator.flatMap{
case And(l,r) => Seq(l,r)
case o:Predicate => Seq(o)
}
}.toList.flatten
println(predicates)
Output :
List(('col1 = 1), ((('col2 >= 1) && ('col2 <= 10)) || (('col2 >= 190) && ('col2 <= 200))), isnotnull('col2))
Here the predicates are still Expressions and hold information (tree representation).
EDIT :
As asked in comment, here's a String (user friendly I hope) representation of the predicates :)
val plan = df.queryExecution.logical
val predicates: Seq[Expression] = plan.children.collect{case f: Filter =>
f.condition.productIterator.flatMap{
case o:Predicate => Seq(o)
}
}.toList.flatten
def stringifyExpressions(expression: Expression): Seq[String] = {
expression match{
case And(l,r) => (l,r) match {
case (gte: GreaterThanOrEqual,lte: LessThanOrEqual) => Seq(s"""${gte.left.toString} between ${gte.right.toString} and ${lte.right.toString}""")
case (_,_) => Seq(l,r).flatMap(stringifyExpressions)
}
case Or(l,r) => Seq(Seq(l,r).flatMap(stringifyExpressions).mkString("(",") OR (", ")"))
case eq: EqualTo => Seq(s"${eq.left.toString} = ${eq.right.toString}")
case inn: IsNotNull => Seq(s"${inn.child.toString} is not null")
case p: Predicate => Seq(p.toString)
}
}
val stringRepresentation = predicates.flatMap{stringifyExpressions}
println(stringRepresentation)
New Output :
List('col1 = 1, ('col2 between 1 and 10) OR ('col2 between 190 and 200), 'col2 is not null)
You can keep playing with the recursive stringifyExpressions method if you want to customize the output.
EDIT 2 : In response to your own edit :
You can change the Or / EqualTo cases to the following
def stringifyExpressions(expression: Expression): Seq[String] = {
expression match{
case And(l,r) => (l,r) match {
case (gte: GreaterThanOrEqual,lte: LessThanOrEqual) => Seq(s"""${gte.left.toString} between ${gte.right.toString} and ${lte.right.toString}""")
case (_,_) => Seq(l,r).flatMap(stringifyExpressions)
}
case Or(l,r) => Seq(l,r).flatMap(stringifyExpressions)
case EqualTo(l,r) =>
val prettyLeft = if(l.resolved && l.dataType == StringType) s"'${l.toString}'" else l.toString
val prettyRight = if(r.resolved && r.dataType == StringType) s"'${r.toString}'" else r.toString
Seq(s"$prettyLeft=$prettyRight")
case inn: IsNotNull => Seq(s"${inn.child.toString} is not null")
case p: Predicate => Seq(p.toString)
}
}
This gives the 4 elements List :
List('col1=1, 'col2 between 1 and 10, 'col2 between 190 and 200, 'col2 is not null)
For the second example :
select * from table where col1=1 and (col2 =2 or (col3 between 1 and 10 or col3 between 190 and 200)) and col4='xyz'
You'd get this output (List[String] with 5 elements) :
List('col1=1, 'col2=2, 'col3 between 1 and 10, 'col3 between 190 and 200, 'col4='xyz')
Additional note: If you want to print the attribute names without the starting quote, you can handle it by printing this instead of toString :
node.asInstanceOf[UnresolvedAttribute].name

Changing cart data during Ajax woocommerce

I'm trying to replace the current WooCommerce cart with a saved one, during Ajax.
This is the code i'm using:
function restore()
{
$current_user_id = get_current_user_id();
if ($current_user_id > 0) {
if (function_exists('get_user_attribute')) {
$buy_now_persistent_cart = get_user_meta($current_user_id, '_buy_now_persistent_cart', true);
error_log(print_r($buy_now_persistent_cart, 1));
if (!empty($buy_now_persistent_cart['cart'])) {
WC()->session->cart = $buy_now_persistent_cart['cart'];
WC()->session->applied_coupons = $buy_now_persistent_cart['applied_coupons'];
if (function_exists('delete_user_attribute')) {
//delete_user_attribute( $current_user_id, '_buy_now_persistent_cart' );
}
//delete_user_meta( $current_user_id, '_buy_now_persistent_cart' );
}
}
}
This is the $buy_now_persistent_cart output:
Array
(
[cart] => Array
(
[3430dcf4efe8aa0c418434656773a73a] => Array
(
[key] => 3430dcf4efe8aa0c418434656773a73a
[product_id] => 126096
[variation_id] => 0
[variation] => Array
(
)
[quantity] => 1
[data_hash] => b5c1d5ca8bae6d4896cf1807cdf763f0
[line_tax_data] => Array
(
[subtotal] => Array
(
)
[total] => Array
(
)
)
[line_subtotal] => 2.4
[line_subtotal_tax] => 0
[line_total] => 2.4
[line_tax] => 0
)
)
[applied_coupons] => Array
(
)
)
When I output WC()->session->cart after setting the new data it seems to have changed correctly, but the updated cart is not there when the Ajax finishes.
I guess it is about saving the cart and/or setting a cart hash and cookies?
I just can't figure it out.
Any help will be appreciated.
I would approach it in a different way. First empty the user cart, then add all the products.
Something like:
if (!empty($buy_now_persistent_cart['cart'])) {
WC()->cart->empty_cart();
foreach($buy_now_persistent_cart['cart'] as $item){
WC()->cart->add_to_cart($item['product_id'], $item['quantity']);
}
}
I didn't tested it, but in general I think it's a better approach than forcing a session

Cakephp sum() with multiplication

Is it possible to find the cakephp with additional condition or can we multiply the sum() field with conditional variable?
I don't know, what could be a best question to let you guys know what I'm asking. so I'm giving a more detail about question. I'm able to find similar data with single array with some trick. but I'm unable to find for this. Please help me or give me an idea to do such task. Thanks.
Using CakePhp 2.6
I want to find data from first table here..
$incentiveweekly=$this->Incentive->find('all',
array('conditions' =>
array(
"AND"=>array(
"Incentive.fromdate >=" => $from,
"Incentive.todate <=" => $to
)
)
)
);
according to number of rows. I have to find another table
Here is the result of above find condition.
Array
(
[Incentive] => Array
(
[id] => 2
[target1] => 3000
[price1] => 1.5
[target2] => 6000
[price2] => 2.5
[target3] => 8000
[price3] => 3.5
[formonth] =>
[type] => 1
[fromdate] => 2016-11-13
[todate] => 2016-11-21
[updatedby] => 1
[created] => 2016-11-15 23:57:21
[modified] => 2016-11-15 23:57:21
)
)
Array
(
[Incentive] => Array
(
[id] => 3
[target1] => 3000
[price1] => 1.5
[target2] => 6000
[price2] => 2.5
[target3] => 8000
[price3] => 3.5
[formonth] =>
[type] => 1
[fromdate] => 2016-11-24
[todate] => 2016-11-28
[updatedby] => 1
[created] => 2016-11-15 23:57:21
[modified] => 2016-11-15 23:57:21
)
)
Now I want to find the array according to number of array record.
$byweek=array(); // Storing Customer data by Target dates in array()
foreach ($incentiveweekly as $weekly){
print_r($weekly);
$target3=$weekly['Incentive']['target3'];
$target2=$weekly['Incentive']['target2'];
$target1=$weekly['Incentive']['target1'];
$price3=$weekly['Incentive']['price3'];
$price2=$weekly['Incentive']['price2'];
$price1=$weekly['Incentive']['price1'];
$byweek[]=$customers=$this->Customer->find('all',array(
'fields'=>array(
'SUM(amount) AS amount',
'created_by'
),
'group' => 'Customer.created_by',
'conditions' => array(
"AND" =>array(
"Customer.created >=" => $weekly['Incentive']['fromdate'],
"Customer.created <=" => $weekly['Incentive']['todate']
)
),
'recursive'=>-1 )
);
//print_r($byweek);
}
I'm getting result like ...
Array
(
[0] => Array
(
[0] => Array
(
[Customer] => Array
(
[created_by] => 3
)
)
)
)
Array
(
[0] => Array
(
[0] => Array
(
[Customer] => Array
(
[created_by] => 3
)
)
)
[1] => Array
(
[0] => Array
(
[Customer] => Array
(
[created_by] => 1
)
)
[1] => Array
(
[Customer] => Array
(
[created_by] => 2
)
)
)
)
But I want that amount would multiply with on the if else condition where I'm using ternary operator.
$value[0]['amount']>=$valuem['Incentive']['target3']?"Target Third":($value[0]['amount']>=$valuem['Incentive']['target2']?"Target Second":($value[0]['amount']>=$valuem['Incentive']['target1']?"Target First":"None"))
Main purpose to find the details are. I want to create an incentive amount where total sales amount should be match with given target amount. If target1 amount one match then incentive would be total amount*price1 and same with target2 and target3. where i'm using tenantry operator. Target price should be multiply(by condition) with the same find condition data.
I search on google and stack overflow but can't find it's solutions. However I'm thankful to stack overflow and all you gusy that i'm able to find a lots of trick and solutions.
I haven't got exactly though you can try with below solution as per my thought,
You need to use WHEN close in MYSQL,
$incenve = 'CASE WHEN amount>5000 THEN "FIRST Target" WHEN amount>3000 THEN "Second Target" ELSE 0 '
and inside fields in above query
'incentive' => $incentive
Thanks Oldskool for this solution Virtualfields with If Condition
Finaly I, Got my solutions by this code bellow. I'm getting result as expected. :)
$this->Customer->virtualFields=array(
'incentive' => "if(SUM(Customer.amount)>=$target3,(SUM(Customer.amount))*$price3,if(SUM(Customer.amount)>=$target2,(SUM(Customer.amount))*$price2,if(SUM(Customer.amount)>=$target1,(SUM(Customer.amount))*$price1,0)))",
);
Now I can use Virtualfied to get the Incentive value.

Why is getResult() only returning an array with only the last record?

I'm writing a console app in Symfony 3, but for some reason my query results are coming back with only 1 result in the array where I confirmed running it in MySQL and get several results back. Here is the relevant code:
$arr_id = array();
$em = $this->getContainer()->get('doctrine')->getManager();
$dql2 = 'SELECT r.productId as pid, COUNT(r.id) as cnt
FROM AppBundle:ReferralTrack r
WHERE r.productId in (:in)
GROUP BY r.productId
ORDER BY cnt DESC';
// $arr_id is populated prior to the next command and is, for example, [1,2,3,4,5]
$rt = $em->createQuery($dql2)
->setParameters(
array(
'in' => implode(',', $arr_id),
)
)
;
$traffic_count = $rt->getResult();
When I run the query in MySql, the exact same query shown by $rt->getSql() and replace the ? in the query with what is echoed out from implode(',', $arr_id), I get a similar result like this:
echo print_r( $traffic_count, 1);
---------------------------------
Array
(
[0] => Array
(
[pid] => 11234
[cnt] => 21
)
)
Here is the query I run in MySQL:
SELECT r0_.product_id AS pid, COUNT( r0_.id ) AS cnt
FROM referral_track r0_
WHERE r0_.product_id
IN ( 11234, 57, 58, 60, 61, 9677, 11216, 11217, 11239, 11296 )
GROUP BY r0_.product_id
ORDER BY cnt DESC
and it returns 7 results. What I have noticed is that getResult() does seem to always return the LAST record, that is what is shown the the array there. What is going on?
Try:
$rt = $em->createQuery($dql2)
->setParameters(
array(
'in' => $arr_id,
)
)
;

How create select/options tag from find('threaded') in CakePHP

How to create select/option html tag from find('threaded') data in CakePHP?
Function find() return results like this:
Array
(
[0] => Array
(
[Forum] => Array
(
[id] => 1
[name] => Forum
)
[children] => Array
(
[0] => Array
(
[Forum] => Array
(
[id] => 3
[name] => Programowanie
[parent_id] => 1
)
)
[1] => Array
(
[Thread] => Array
(
[id] => 11
[name] => Nowe forumowisko
[parent_id] => 1
)
)
)
)
[1] => Array
(
[Forum] => Array
(
[id] => 4
[name] => Nauka
[parent_id] => 0
)
[children] => Array
(
)
)
)
How?
there is a build in method for tree like results to be made into a list for select option tags:
$this->Model->generateTreeList($conditions, null, null, ' - ', $recursive);
instead of using find(threaded)
that is if you attached the Tree behavior to it (which you probably should have since its obviously a tree like model).
But if you want to keep your find(threaded) method you need to manually transform it via recursive method.
thanks DSkinner, very informative..
i have modified it to be more generic:
/**
* Returns an indented html select based on children depth
*
* #param array $data_array - Array of data passed in from cake's find('threaded') feature
* #param array $model - the model name
* #param array $key - the key field on the model
* #param array $value - the value field on the model
* #param array $list - Used internally, contains array to be returned
* #param int $counter - Used Internally, counter for depth
* #return array
*/
public function threaded_to_list($data_array, $model=null, $key='id', $value='name',
&$list = array(), $counter = 0, $separator='__')
{
if ( ! is_array($data_array))
return array();
foreach ($data_array AS $data)
{
$list[$data[$model][$key]] = str_repeat($separator, $counter).$data[$model][$value];
if ( ! empty($data['children']))
{
$this->threaded_to_list($data['children'], $model, $key, $value, $list, $counter + 1);
}
}
return $list;
}
Here's what worked for me.
Make sure you replace:
{SELECT_ID} with the value of the drop down
{SELECT_LABEL} with what is displayed as the option
{MODEL_NAME}
with your model name
/**
* Returns an indented html select based on children depth
*
* #param array $data_array - Array of data passed in from cake's find('threaded') feature
* #param array $list - Used internally, contains array to be returned
* #param int $counter - Used Internally, counter for depth
* #return array
*/
public function drop_down_from_threaded($data_array, &$list = array(), $counter = 0)
{
if ( ! is_array($data_array))
return array();
foreach ($data_array AS $data)
{
$list[$data[{SELECT_ID}]] = str_repeat(' ', $counter).$data[{SELECT_LABEL}];
if ( ! empty($data['children']))
{
$this->drop_down_from_threaded($data['children'], $list, $counter + 1);
}
}
return $list;
}
/**
* Get the data from the find('threaded') and pass it to our new function
*/
$results = $this->{MODEL_NAME}->find('threaded');
$results = $this->drop_down_from_threaded($results);
This may not work 100% for everyone, it works for me, but it should help give you something to start with.
What are "children"? Seems like your tree is spawned across one-to-many relations
It is not necessary to use the Tree behavior to use this method - but all desired results must be possible to be found in a single query.