How can I chain having() clause on my eloquent request - eloquent

I have to make a request to filter some datas on my laravel app (v8).
I'm using livewire to filtering datas on a table.
The full request :
$datas = Client::withSum(
[ 'statistics_products as statistics_products_sum_'.$this->n_1 => fn ($query) => $query->where('yr', $this->n_1)],
'total_ht')
->withSum(
[ 'statistics_products as statistics_products_sum_'.$this->n_2 => fn ($query) => $query->where('yr', $this->n_2)],
'total_ht')
->withSum(
[ 'statistics_products as statistics_products_sum_'.$this->n => fn ($query) => $query->where('yr', $this->n)],
'total_ht')
// For is_deleted selection
->when($this->deleted, function ($query, $deleted) {
if($deleted == 'oui') {
$query->where('is_delete', 1);
} elseif($deleted === 'non') {
$query->where('is_delete', 0);
}
})
// For dpt selection
->when($this->dpt, function ($query, $dpt) {
$query->where('postal_code', 'LIKE', $this->dpt. '%');
})
// For referent selection
->when($this->referent, function ($query, $referent) {
if($referent === 'oui') {
$query->whereColumn('client_num', 'sign_num');
} elseif($referent === 'non') {
$query->whereColumn('client_num', '!=', 'sign_num');
}
})
->when($this->ca, function ($query, $ca) {
if($this->year != null) {
if($ca === 'A') {
$query->having('statistics_products_sum_'.$this->year, '<', 20000)->orHaving('statistics_products_sum_'.$this->year, '=', null);
}elseif($ca === 'B') {
$query->havingBetween('statistics_products_sum_'.$this->year, [20001, 40000]);
}elseif($ca === 'C') {
$query->havingBetween('statistics_products_sum_'.$this->year, [40001, 60000]);
}elseif($ca === 'D') {
$query->havingBetween('statistics_products_sum_'.$this->year, [60001, 100000]);
}elseif($ca === 'E') {
$query->havingBetween('statistics_products_sum_'.$this->year, [100001, 500000]);
}elseif($ca === 'F') {
$query->having('statistics_products_sum_'.$this->year, '>', 500000);
}
}
})
// For search
->when($this->search, function ($query, $search) {
$query->searchIn3Columns('society_name', 'city','postal_code', $search);
})
->paginate($this->pagination_number);
But this part doesn't work properly :
if($ca === 'A') {
$query->having('statistics_products_sum_'.$this->year, '<', 20000)
->orHaving('statistics_products_sum_'.$this->year, '=', null);
}
Here I only get results for 'statistics_products_sum_'.$this->year, '<', 20000
I don't get the result where it's null...
Do you know how can I chain two having clause?

This part of the query doesn't seem right:
->orHaving('statistics_products_sum_'.$this->year, '=', null); // = null ???
Maybe try with:
if ($ca === 'A') {
$query->having('statistics_products_sum_' . $this->year, '<', 20000)
->orWhereNull('statistics_products_sum_' . $this->year);
}

Related

Svelte doesn't reorder Meteor collection

My Svelte component is set up to find all people in a MongoDB document and list them in a table. When clicking on a column header the collection should sort by that column/field and it should toggle the sort direction with subsequent clicks.
My script section:
$: sortColumn = 'name';
$: sortDirection = 'asc';
$: sortParameters = setSortParams(sortColumn, sortDirection);
$: contactList = [];
function getContactList(sortObj) {
contactList = Contacts.find({
isBlocked: false,
isDeleted: { $ne: true }
},
{
sort: sortObj
}).fetch();
contactList = contactList;
}
onMount(() => {
getContactList(setSortParams(sortColumn, sortDirection));
});
function changeSortDirection() {
if (sortDirection === 'asc') {
sortDirection = 'desc';
} else {
sortDirection = 'asc';
}
}
function sortByColumn(col) {
if (col === sortColumn) {
changeSortDirection();
} else {
sortDirection = 'asc';
}
sortColumn = col;
getContactList(setSortParams(sortColumn, sortDirection));
}
function setSortParams(sortField, sDirection) {
let sortParams = [];
let direction = sDirection || 1;
let field = sortField || 'name';
if (direction === 'asc') {
direction = 1;
} else {
direction = -1;
}
if (field === 'name') {
sortParams.push(['firstName', direction]);
sortParams.push(['lastName', direction]);
} else {
sortParams.push([field, direction]);
}
sortParams = sortParams;
return sortParams;
}
And the relevant part of my svelte file:
{#each columns as column}
<th class="contact-table__column contact-table__column-header"
on:click={() => sortByColumn(column.type)}>
<span class="contact-table__title">{column.display} {sortDirection}</span>
</th>
{/each}
The collection reorders when I click on a different column header, but it doesn't reorder when I click on the same header (it should switch between ASC and DESC sort order).
I'm new to Svelte and Meteor so I'm sure there's a few things I'm doing wrong. I appreciate any help.

Need a faster eloquent search query

I have two models user and actor with one to one relation. User table has name, email(unique) and user type(actor/filmmaker) column.
I want to get all actors details. For that, I am using the following code.
$actorlist= Actor::with('user')->paginate(15);
but it is very slow when the number of actors is more.
Also for search functionality, I am using the following code.
*$actorlist = Actor::join('users', function ($join) {
$join->on('actors.user_id', '=', 'users.id');
})->newQuery();
if ($request->has('has_voice')) {
$actorlist->has('voices');
}
if ($request->has('has_video')) {
$actorlist->has('shows');
}
if ($request->has('has_imdb')) {
$actorlist->where('imdb_link', '!=', null);
}
if ($request->has('hair_colour') && $request->input('hair_colour') != 'any hair colour') {
$actorlist->where('hair_colour', 'LIKE', $request->input('hair_colour'));
}
if ($request->has('gender') && $request->input('gender') != 'any gender') {
$actorlist->where('gender', 'LIKE', $request->input('gender'));
}
if ($request->has('ethnicity') && $request->input('ethnicity') != 'any ethnicity') {
$actorlist->where('ethnicity', 'LIKE', "%{$request->input('ethnicity')}%");
}
if ($request->has('eye_colour') && $request->input('eye_colour') != 'any eye colour') {
$actorlist->where('eye_colour', 'LIKE', $request->input('eye_colour'));
}
if ($request->has('hair_colour') && $request->input('hair_colour') != 'any hair colour') {
$actorlist->where('hair_colour', 'LIKE', $request->input('hair_colour'));
}
if ($request->has('min_age')) {
$actorlist->where('min_age', '>=', $request->input('min_age'));
}
if ($request->has('max_age')) {
$actorlist->where('max_age', '<=', $request->input('max_age'));
}
if ($request->has('min_height') && $request->has('max_height')) {
$actorlist->whereBetween('height', [floatval($request->input('min_height')), floatval($request->input('max_height'))]);
}
if($request->has('name') && $request->input('name') != ''){
$keywords = $searchValues = preg_split('/\s+/', $request->input('name'), -1, PREG_SPLIT_NO_EMPTY);
$actorlist->where(function ($q) use ($keywords) {
foreach ($keywords as $value) {
$q->orWhere('users.first_name', 'like', "%{$value}%");
$q->orWhere('users.last_name', 'like', "%{$value}%");
}
});
}
$actorlist = $actorlist->paginate(15);*
This is taking almost 5mins to load.
Please help me with feasible solutions.
Thanks in advance.

How can I programmatically create nested where clauses with Zend\Db\Sql component?

I've tried using the following code to accomplish it, but the unnest function returns an error:
foreach($params as $key=>$param) {
if(strpos($param, ',') !== false) {
$where = new \Zend\Db\Sql\Where();
$where->nest();
$param_arr = explode(',', $param);
$entered_once = 0;
foreach($param_arr as $p) {
$where->equalTo($key, $p);
if($entered_once < count($param_arr)) {
$where->or;
}
$entered_once++;
}
$where->unnest();
$select->where($where);
}
else {
$select->where(array($key => $param));
}
}
I've figured out what I'm doing wrong: I didn't realize that the nest() function returned a brand new PredicateSet and that's what I needed to call everything on. The solution is as follows:
foreach($params as $key=>$param) {
if(strpos($param, ',') !== false) {
$where = new \Zend\Db\Sql\Where();
$predicate_set = $where->nest();
$param_arr = explode(',', $param);
$entered_once = 0;
foreach($param_arr as $p) {
$predicate_set->equalTo($key, $p);
if($entered_once < count($param_arr)) {
$predicate_set->or;
}
$entered_once++;
}
$predicate_set->unnest();
$select->where($where);
}
else {
$select->where(array($key => $param));
}
}

Sending messages with facebook xmpp api

I have copied and modified some of the facebook's given chat api code, now I want to send a message to my friend. I found that we send a xml <message from="" to=""> to send a message. But that did not happen. maybe it's because i don't know what to put on from and to attribs?
The Code:
<?php
$STREAM_XML = '<stream:stream '.
'xmlns:stream="http://etherx.jabber.org/streams" '.
'version="1.0" xmlns="jabber:client" to="chat.facebook.com" '.
'xml:lang="en" xmlns:xml="http://www.w3.org/XML/1998/namespace">';
$AUTH_XML = '<auth xmlns="urn:ietf:params:xml:ns:xmpp-sasl" '.
'mechanism="X-FACEBOOK-PLATFORM"></auth>';
$CLOSE_XML = '</stream:stream>';
$RESOURCE_XML = '<iq type="set" id="3">'.
'<bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">'.
'<resource>fb_xmpp_script</resource></bind></iq>';
$SESSION_XML = '<iq type="set" id="4" to="chat.facebook.com">'.
'<session xmlns="urn:ietf:params:xml:ns:xmpp-session"/></iq>';
$START_TLS = '<starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"/>';
$MESSAGE = '<message from="-cyberkiller.nishchal#chat.facebook.com" to="-nootan.ghimire#chat.facebook.com">
<body>This is the test message! Sent from App. by, "Nishchal"</body>
</message>';
function open_connection($server) {
$fp = fsockopen($server, 5222, $errno, $errstr);
if (!$fp) {
print "$errstr ($errno)<br>";
} else {
print "connnection open<br>";
}
return $fp;
}
function send_xml($fp, $xml) {
fwrite($fp, $xml);
}
function recv_xml($fp, $size=4096) {
$xml = fread($fp, $size);
if (!preg_match('/^</', $xml)) {
$xml = '<' . $xml;
}
if ($xml === "") {
return null;
}
$xml_parser = xml_parser_create();
xml_parse_into_struct($xml_parser, $xml, $val, $index);
xml_parser_free($xml_parser);
return array($val, $index);
}
function find_xmpp($fp, $tag, $value=null, &$ret=null) {
static $val = null, $index = null;
do {
if ($val === null && $index === null) {
list($val, $index) = recv_xml($fp);
if ($val === null || $index === null) {
return false;
}
}
foreach ($index as $tag_key => $tag_array) {
if ($tag_key === $tag) {
if ($value === null) {
if (isset($val[$tag_array[0]]['value'])) {
$ret = $val[$tag_array[0]]['value'];
}
return true;
}
foreach ($tag_array as $i => $pos) {
if ($val[$pos]['tag'] === $tag && isset($val[$pos]['value']) &&
$val[$pos]['value'] === $value) {
$ret = $val[$pos]['value'];
return true;
}
}
}
}
$val = $index = null;
} while (!feof($fp));
return false;
}
function xmpp_connect($options, $access_token) {
global $STREAM_XML, $AUTH_XML, $RESOURCE_XML, $SESSION_XML, $CLOSE_XML, $START_TLS;
$fp = open_connection($options['server']);
if (!$fp) {
return false;
}
send_xml($fp, $STREAM_XML);
if (!find_xmpp($fp, 'STREAM:STREAM')) {
return false;
}
if (!find_xmpp($fp, 'MECHANISM', 'X-FACEBOOK-PLATFORM')) {
return false;
}
send_xml($fp, $START_TLS);
if (!find_xmpp($fp, 'PROCEED', null, $proceed)) {
return false;
}
stream_socket_enable_crypto($fp, true, STREAM_CRYPTO_METHOD_TLS_CLIENT);
send_xml($fp, $STREAM_XML);
if (!find_xmpp($fp, 'STREAM:STREAM')) {
return false;
}
if (!find_xmpp($fp, 'MECHANISM', 'X-FACEBOOK-PLATFORM')) {
return false;
}
send_xml($fp, $AUTH_XML);
if (!find_xmpp($fp, 'CHALLENGE', null, $challenge)) {
return false;
}
$challenge = base64_decode($challenge);
$challenge = urldecode($challenge);
parse_str($challenge, $challenge_array);
$resp_array = array(
'method' => $challenge_array['method'],
'nonce' => $challenge_array['nonce'],
'access_token' => $access_token,
'api_key' => $options['app_id'],
'call_id' => 0,
'v' => '1.0',
);
$response = http_build_query($resp_array);
$xml = '<response xmlns="urn:ietf:params:xml:ns:xmpp-sasl">'.
base64_encode($response).'</response>';
send_xml($fp, $xml);
if (!find_xmpp($fp, 'SUCCESS')) {
return false;
}
send_xml($fp, $STREAM_XML);
if (!find_xmpp($fp,'STREAM:STREAM')) {
return false;
}
if (!find_xmpp($fp, 'STREAM:FEATURES')) {
return false;
}
send_xml($fp, $RESOURCE_XML);
if (!find_xmpp($fp, 'JID')) {
return false;
}
send_xml($fp, $SESSION_XML);
if (!find_xmpp($fp, 'SESSION')) {
return false;
}
send_xml($fp, $MESSAGE);
if (!find_xmpp($fp, 'BODY')) {
return false;
}
send_xml($fp, $CLOSE_XML);
print ("Authentication complete<br>");
fclose($fp);
return true;
}
function get_access_token(){
$token=new Facebook(array("AppId"=>"my app id","AppSecret"=>"my app secret"));
$token=$facebook->getAccessToken();
return $token;
}
function _main() {
require_once("facebook.php");
$app_id='app id';
$app_secret='app secret';
$my_url = "http://localhost/message.php";
$uid = 'cyberkiller.nishchal#chat.facebook.com';
$access_token = get_access_token();
$options = array(
'uid' => $uid,
'app_id' => $app_id,
'server' => 'chat.facebook.com',
);
if (xmpp_connect($options, $access_token)) {
print "Done<br>";
} else {
print "An error ocurred<br>";
}
}
_main();
so what do I need to do to send a message to that user through this, i tried to create a xml with the message but got strucked there, can any one please suggest something, When I run the code, socket enable crypto is being executed after that it is taking some time like 20 secs, then it displays an error occured, do I have to remove the send_xml($fp,$STREAM_XML); for the second time after the stream_socket_enable_crypto($fp, false, STREAM_CRYPTO_METHOD_TLS_CLIENT);
I changed the second parameter of this call to false because I don't have an ssl connection, what should I do next?
Use Facebook ID instead of the url username.Get it by requesting http://graph.facebook.com/{username}
Then replace it on "from" and "to" attributes.Also remove the hyphen on "from" attribute, or just remove all of it (from my experience its still going to work).Hyphen on "to" attribute is mandatory.

Saving in mongoDb with Mongoose, unexpected elements saved

When I write in my mongoDB with mongoose the operation is treated with success, my document is saved, but there is also all kind of weird other sutff written down. It seems to be mongoose code. What could cause this?
I add stuff in a specific array with:
resultReference.ref[arrayLocation].allEvents.push(theEvent);
{id: 11, allEvents: [] } is the structure of a ref element, and I push theEvent in the allEvents array. I then resultReference.save()
I use express, mongoose and mongoHQ for database. I tried on a local mongo server, and this annoyance is still there. I've print in my console the document to write before save() and non of this weird code is there.
{
id 11
allEvents
[
0
{
_events
{
maxListeners 0
}
_doc
{
_id {"$oid": "4eb87834f54944e263000003"}
title "Test"
allDay false
start 2011-11-10 13:00:00 UTC
end 2011-11-10 15:00:00 UTC
url "/test/4eb87834f54944e263000002"
color "#99CCFF"
ref "4eb87834f54944e263000002"
}
_activePaths
{
paths
{
title "modify"
allDay "modify"
start "modify"
end "modify"
url "modify"
color "modify"
ref "modify"
}
states
{
init
{ }
modify
{
title true
allDay true
start true
end true
url true
color true
ref true
}
require
{ }
}
stateNames
[
0 "require"
1 "modify"
2 "init"
]
}
_saveError null
_validationError null
isNew true
_pres
{
save
[
0
function (next) {
// we keep the error semaphore to make sure we don't
// call `save` unnecessarily (we only need 1 error)
var subdocs = 0
, error = false
, self = this;
var arrays = this._activePaths
.map('init', 'modify', function (i) {
return self.getValue(i);
})
.filter(function (val) {
return (val && val instanceof DocumentArray && val.length);
});
if (!arrays.length)
return next();
arrays.forEach(function (array) {
subdocs += array.length;
array.forEach(function (value) {
if (!error)
value.save(function (err) {
if (!error) {
if (err) {
error = true;
next(err);
} else
--subdocs || next();
}
});
});
});
}
1 "function checkForExistingErrors(next) {
if (self._saveError){
next(self._saveError);
self._saveError = null;
} else {
next();
}
}"
2 "function validation(next) {
return self.validate.call(self, next);
}"
]
}
_posts
{
save
[ ]
}
save
function () {
var self = this
, hookArgs // arguments eventually passed to the hook - are mutable
, lastArg = arguments[arguments.length-1]
, pres = this._pres[name]
, posts = this._posts[name]
, _total = pres.length
, _current = -1
, _asyncsLeft = proto[name].numAsyncPres
, _next = function () {
if (arguments[0] instanceof Error) {
return handleError(arguments[0]);
}
var _args = Array.prototype.slice.call(arguments)
, currPre
, preArgs;
if (_args.length && !(arguments[0] === null && typeof lastArg === 'function'))
hookArgs = _args;
if (++_current < _total) {
currPre = pres[_current]
if (currPre.isAsync && currPre.length < 2)
throw new Error("Your pre must have next and done arguments -- e.g., function (next, done, ...)");
if (currPre.length < 1)
throw new Error("Your pre must have a next argument -- e.g., function (next, ...)");
preArgs = (currPre.isAsync
? [once(_next), once(_asyncsDone)]
: [once(_next)]).concat(hookArgs);
return currPre.apply(self, preArgs);
} else if (!proto[name].numAsyncPres) {
return _done.apply(self, hookArgs);
}
}
, _done = function () {
var args_ = Array.prototype.slice.call(arguments)
, ret, total_, current_, next_, done_, postArgs;
if (_current === _total) {
ret = fn.apply(self, args_);
total_ = posts.length;
current_ = -1;
next_ = function () {
if (arguments[0] instanceof Error) {
return handleError(arguments[0]);
}
var args_ = Array.prototype.slice.call(arguments, 1)
, currPost
, postArgs;
if (args_.length) hookArgs = args_;
if (++current_ < total_) {
currPost = posts[current_]
if (currPost.length < 1)
throw new Error("Your post must have a next argument -- e.g., function (next, ...)");
postArgs = [once(next_)].concat(hookArgs);
return currPost.apply(self, postArgs);
}
};
if (total_) return next_();
return ret;
}
};
if (_asyncsLeft) {
function _asyncsDone (err) {
if (err && err instanceof Error) {
return handleError(err);
}
--_asyncsLeft || _done.apply(self, hookArgs);
}
}
function handleError (err) {
if ('function' == typeof lastArg)
return lastArg(err);
if (errorCb) return errorCb.call(self, err);
throw err;
}
return _next.apply(this, arguments);
}
errors null
}
]
}
]
The reason this happened is because I didnt save my schema in mongoose in the proper order. This would mean declaring your child schema before a parent to get proper behavior.