Laravel count query - laravel

Something is strange.I try to check if query gives at least one object in collection. It has always worked, but now, it does not anymore.
$myObj = User::whereRaw("lower(name) = '".strtolower(trim("toto"))."'");
if ( $myObj->count() > 0) {
\Log::info( "Good" );
}
Code stops working. but if I add:
$myObj = User::whereRaw("lower(name) = '".strtolower(trim("toto"))."'");
\Log::info( $myObj->count() );
if ( $myObj->count() > 0) {
\Log::info( "Good" );
}
it displays the number of objects returned by query, before breaking the code.
What is wrong, please?

Possibly, you omit the method get() to fetch all records, maybe it could be:
$myObj = User::whereRaw("lower(name) = '".strtolower(trim("toto"))."'")->get();

Related

Modify single Item of Laravel Collection without mapping every single item

I loop trough an eloquent Collection and I want to add the data to another Collection called "$tagCollection". If an entry with the same tag_id already exists I only want to increase the rating-column for the existing entry.
At the moment it looks like this. Has anyone an Idea?
$tagCollection = collect();
$entries->each(function($entry) use($tagCollection){
$tagId = $entry->tag_id;
//something like this
if($tagCollection->contains('tag_id', $tagId)){
$tagCollection->update ('rating' => $oldRating + 0.5)
} else{
$tagCollection->push(array(
'tag_id' => $tagId,
'rating' => 0.35
));
}
});
I also tried to use ->pull() to remove the Item out of the Collection and then push it again with the new rating but I also do not know how
Can you do it with array instead of collection? For example:
$tagArray = [];
$entries->each(function ($entry) use (&$tagArray) {
if (isset($tagArray[$entry['tag_id']])) {
$tagArray[$entry['tag_id']] += 0.5;
} else {
$tagArray[$entry['tag_id']] = 0.35;
}
});
If the end goal is to update all the entries present in $entries that belong to a specific $tagId, then you can do this
$entryIds = $entries->where('tag_id',$tagId)->pluck('id')->toArray();
Entry::whereIn('id', $entryIds)->update(['rating' => \DB::raw('rating + 0.5')]);
And thats it.

Laravel: Using OR in multiple Where Claus

Converting SQL to Laravel format is still a bit confusing for me. I need to use OR. If onloan = NULL OR 0 then display record.
The code below can only detect the 0 but not the NULL.
public function finditembarcode () {
if ($finditembarcode = \Request::get('q')) {
$itembarcode = Item::where(Item::raw("BINARY `itembarcode`"), $finditembarcode)
->where('onloan','=', NULL OR 0)
->paginate();
}else{
$itembarcode = ''; //If nothing found, don't return anything.
}
return $itembarcode;
}
I also tried but get the same result as code above.
->where('onloan','=', NULL || 0)
Laravel Database Query Builder whereNull / whereNotNull / orWhereNull / orWhereNotNull
->where('onloan', 0)->orWhereNull('onloan')

laravel get eloquent return null for specific column if another column is not specific word

I have query something like this:
Order::where('order_id', 2)
->leftJoin('test', 'test.order_id', '=', 'orders.order_id')
->get(['order.status, 'order.path', 'test.name']);
Now, what I want to achieve is the following. in get clause, when fetching specific columns, if 'order.status' isn't COMPLETED, return 'order.path' as null, if 'order.status' is COMPLETED, then return actual order.path
You should try to loop the result, then apply the change what you want.
$orders = Order::where('order_id', 2)
->leftJoin('test', 'test.order_id', '=', 'orders.order_id')
->get(['order.status, 'order.path', 'test.name']);
for($i = 0; i < orders.lenght();i++){
if(orders[i].status != 'COMPLETED'){
orders[i].path = null;
}
}

How can I assign an order to a certain shop manager in Woocommerce

we have a services woocommerce online shop with three shop managers.
We would like to filter new orders and assign them to one of these three managers. The managers only can see their assigned orders, and can't access or see the rest.
Maybe this could be done by filtering the backend view (admin panel) via custom_field, but I don't know if it is a good approach. Maybe there is a plugin based on role capabilites.
Any suggest?
Thanks.
After having the same issue I combined the solutions of similar, already answered questions and it worked. I know the question is old, but someone may find it helpful. Here is one possible solution:
Add custom meta key containing your desired store_manager id to every order (in my case if a order was from a specific country I wanted only a sprecific store_manager to see it, you can put your custom logic in the before_checkout_create_order() function)
function before_checkout_create_order($order, $data) {
$country = $order->billing_country;
$store_manager_id = '';
$belgium_region = ['BE', 'NL', 'DE'];
$czech_region = ['CZ', 'AT', 'SI', 'HU'];
$uk_region = ['GB'];
if (in_array($country, $belgium_region)) {
// Manually assigning the _store_manager_id using the user id, yours will differ
$store_manager_id = 7;
} else if (in_array($country, $czech_region)) {
$store_manager_id = 3;
} else if (in_array($country, $uk_region)) {
$store_manager_id = 2;
} else {
$store_manager_id = 1;
}
$order->update_meta_data('_store_manager_id', $store_manager_id);
}
add_action('woocommerce_checkout_create_order', 'before_checkout_create_order', 20, 2);
I found the method for assigning custom meta keys to a order ON THIS THREAD you can see what the woocommerce_checkout_create_order and $order->update_meta_data() hook and method do there, it's already greatly explained by its author
Filter the Woocommerce Admin Order list to only show current user assigned orders (but let Master Admin view all orders also)
function custom_admin_shop_manager_orders($query) {
global $pagenow;
$qv = &$query->query_vars;
$currentUserRoles = wp_get_current_user()->roles;
$user_id = get_current_user_id();
if (in_array('shop_manager', $currentUserRoles)) {
if ( $pagenow == 'edit.php' &&
isset($qv['post_type']) && $qv['post_type'] == 'shop_order' ) {
// I use the meta key from step 1 as a second parameter here
$query->set('meta_key', '_store_manager_id');
// The value we want to find is the $user_id defined above
$query->set('meta_value', $user_id);
}
}
return $query;
}
add_filter('pre_get_posts', 'custom_admin_shop_manager_orders');
As you can see we check if the current user role is shop_manager so all the logic after that doesn't count if you're the admin - you will see all the orders, but if you are a shop_manager you will get only your orders. The edit.php is the woocommerce orders list page.
I found the second step in THIS THREAD so you can found more info there also.
Hope this helps you!
This function makes the orders display only to its own authors (shop managers):
function alter_the_edit_screen_query( $wp_query ) {
if ( ( strpos( $_SERVER[ 'REQUEST_URI' ], '/wp-admin/edit.php' ) !== false ) and ( strpos( $_SERVER[ 'REQUEST_URI' ], '/wp-admin/edit.php?post_type=unit' ) === false ) and ( strpos( $_SERVER[ 'REQUEST_URI' ], '/wp-admin/edit.php?post_type=course' ) === false ) ) {
if ( !current_user_can( 'activate_plugins' ) ) {
add_action( 'views_edit-post', 'remove_items_from_edit' );
global $current_user;
$wp_query->set( 'author', $current_user->id );
}
}
}
add_filter('parse_query', 'alter_the_edit_screen_query' );
function remove_items_from_edit( $views ) {
unset($views['all']);
unset($views['publish']);
unset($views['trash']);
unset($views['draft']);
unset($views['pending']);
return $views;
}
This other function hides "All orders" tab to no-admin users (as shop manager):
function my_custom_admin_head() {
if ( ! current_user_can( 'update_core' ) ) {
echo '<style type="text/css">
ul.subsubsub li.all { display:none!important; }
</style>';
}
}
add_action( 'admin_head', 'my_custom_admin_head' );

issue using Linq Any clause in Predicatebuilder

I am having an issue with the LinqKit predicatebuilder. I have used it in the past for simple queries and it has worked fine but I am now trying to use it with an Any clause in the statement and it seems to be giving me random results. Below is the code I am using to build the statement. Can anyone see what I am doing wrong? Is there a better and easier way to do what I want to do. I am using predicatebuilder right now because there is a very complex query I am building which could contain nested predicates and such and I have seen no other easy way to do this. I am using this with entity framework.
if (cqv.ComplexQuery.IncludeOnAll)
{
Includepredicate = PredicateBuilder.True<Customer>();
}
else
{
Includepredicate = PredicateBuilder.False<Customer>();
}
inner = PredicateBuilder.True<Customer>();
if (a.Include == true || a.Exclude == true)
{
productinner = PredicateBuilder.True<CustomerProduct>();
if (a.VersiondID != 0)
{
productinner = productinner.And(o => o.ProductTypeID == a.ProductType.ID && o.VersionID == a.VersiondID);
inner = inner.And(o => o.Products.Any(productinner.Compile()));
}
else
{
productinner = productinner.And(o => o.ProductTypeID == a.ProductType.ID);
inner = inner.And(o => o.Products.Any(productinner.Compile()));
}
if (cqv.ComplexQuery.IncludeOnAll)
{
Includepredicate = Includepredicate.And(inner.Expand());
}
else
{
Includepredicate = Includepredicate.Or(inner.Expand());
}
}
IncludedCustomers = UoW.Customers.AsExpandable().Where(Includepredicate).ToList();
//This second list does the exact query the first one should be doing so I could compare results. The reuslts are totally different. Not only are there more results using predicatebuilder but they seem random
List<Customer> test = UoW.Customers.Where(o => o.Products.Any(s => s.ProductTypeID == 1)).ToList();
I don't see any easy way to try to debug issue with predicate builder either. Does anyone know of a quick way to determine the SQL that gets created from this query?
EDIT ----------------------------------------------
So I have solved part of my issue but run into another one. the issue with the Any clause and random results was fixed by me setting in integer variable with the a.ProductType.ID and using that value in the clause. Once I did that I got the results I expected. Now my issue is that even though this works fine when 1 product is select if I select naymore than 1 instead of either looking for any customers that have both of these products or either of these products the results I gt is always just the customer with the last product I put a clause in for. I will put my updated code below
foreach (CustomerProductQueryProduct a in cqv.ComplexQuery.Products)
{
inner = PredicateBuilder.True<Customer>();
if (a.Include == true || a.Exclude == true)
{
value = a.ProductType.ID;
productinner = PredicateBuilder.True<CustomerProduct>();
if (a.VersiondID != 0)
{
productinner = productinner.And(s => s.ProductTypeID == value && s.VersionID == a.VersiondID);
inner = inner.And(o => o.Products.Any(productinner.Compile()));
}
else
{
productinner = productinner.And(s => s.ProductTypeID == value);
inner = inner.And(o => o.Products.Any(productinner.Compile()));
}
if (cqv.ComplexQuery.IncludeOnAll)
{
Includepredicate = Includepredicate.And(inner.Expand());
}
else
{
Includepredicate = Includepredicate.Or(inner.Expand());
}
}
}
IncludedCustomers = UoW.Customers.AsExpandable().Where(Includepredicate).ToList();
Is PredicateBuilder not able to handle multiple Any clauses?
I finally figured out that I need to make temporary variable inside of my for loop to hold the value. When you do that it somehow knows to resolve the value immediately and the predicates work.

Resources