Criteria expression on ArrayCollection is case sensitive - symfony

I have an ArrayCollection from Hashtag entity (database/table collation both set to utf8_bin_ci) which I want to match on a Criteria but it's not case insensitive.
I've tried 'contains', 'eq', 'startsWith', 'endsWith' expressions, but it returns null on matching, however it has many results without the Criteria matching.
If I add strtolower / strtoupper to $this->name property, it works in the specified case.
How can I make it case-insensitive the Criteria or the matching here?
public function getHashtags($max = null) {
$hashtags = $this->hashtags;
$hashtags->getIterator();
$crit = Criteria::create()
->where(Criteria::expr()->contains('name', $this->name))
if (!empty($max)) {
$crit->setMaxResults($max);
}
return $hashtags->matching($crit);
}

Your code calls getIterator(), which will prevent any database magic from ever happening, because it initializes the collection (which loads all entries), so your collation doesn't matter anyway.
Also, the contains function uses strpos, which obviously is not case-insensitive.
Since your code already pulls in all hashtags, just filter it already:
$hashtags = array_filter(function(Hashtag $hashtag) {
return stripos($this->name, $hashtag->getName());
}, $this->hashtags);
if(!empty($max)) {
$hashtags = array_slice($hashtags, 0, $max, true);
// remove true, if you don't care about keys ^, this preserves them
}
return $hashtags;

regard to #Jakumi correct answer:
$hashtags = array_filter($this->hashtags->toArray(), function (TwitterHashtag $hashtag) use ($fields) {
foreach ($fields as $field) {
if (false !== stripos($hashtag->getName(), $this->$field)) {
return true;
}
}
});
if (!empty($max)) {
$hashtags = array_slice($hashtags, 0, $max, false);
}

Related

GET params set to "false" - philosophic question [duplicate]

What is the preferred way to specify boolean value in the query part of URI? A normal query string looks like
a=foo&b=bar
Say I have a parameter "c" with boolean value, should I state
a=foo&b=bar&c=1
Or
a=foo&b=bar&c=True
Or
a=foo&b=bar&c=true
I checked the query component section of RFC 2396 and it does not specify how to express a boolean parameter. So what I want to know is what is the common (or reasonable) way to do it?
It completely depends on the way you read the query string. All of these that you ask for are valid.
Use key existence for boolean parameter like ?foo
For example, use ?foo instead of ?foo=true.
I prefer this way because I don't need to waste time to think or trace the source code about whether it should be true or 1 or enable or yes or anything that beyond my imagination.
In the case of case sensitivity, should it be true or True or TRUE?
In the case of term stemming, should it be enable or enabled?
IMHO, the form of ?foo is the most elegant way to pass a boolean variable to server because there are only 2 state of it (exist or not exist), which is good for representing a boolean variable.
This is also how Elasticsearch implemented for boolean query parameter, for example:
GET _cat/master?v
In node with an express server, you can add a boolean parser middleware like express-query-boolean.
var boolParser = require('express-query-boolean');
// [...]
app.use(bodyParser.json());
app.use(boolParser());
Without
// ?a=true&b[c]=false
console.log(req.query);
// => { a: 'true', b: { c: 'false' } }
With
// ?a=true&b[c]=false
console.log(req.query);
// => { a: true, b: { c: false } }
Url are strings and all values in a URL are strings,
all the params will be returned as strings.
it depends on how you interpret it in your code.
for the last one where c = true
you can do a JSON.parse(c)
which will change it to a boolean.
Also, you have to be careful not to pass it an empty string, if not it will throw an error.
I managed this with a custom function.
See browser compatibility here: https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams
function parseQuery(url = window.location.search) {
const urlParams = new URLSearchParams(url);
return Array.from(urlParams.keys()).reduce((acc, key) => {
const value = urlParams.get(key);
if (value) {
switch (value) {
case 'false': {
acc[key] = false;
break;
}
case 'true': {
acc[key] = true;
break;
}
case 'undefined': {
acc[key] = undefined;
break;
}
case 'null': {
acc[key] = null;
break;
}
default: {
acc[key] = value;
}
}
}
return acc;
}, {});
}
The function returns an object with all the parsed query parameters and fallback by default to the original value.
Or you can do this
const queryBool = unwrapTextBoolean({{{A_WAY_TO_GET_THAT_TEXT_BOOLEAN}}})
if(queryBool===null) {return;}
if(queryBool){
/*true-based code*/
}else{
/*false-based code*/
}
function unwrapTextBoolean(tB){
if(tB === 'true') return true;
if(tb === 'false') return false;
return null;
}

codeigniter recursive model function returning blank but when printing it in the model showing properly

codeigniter recursive model function returning blank but when printing it in the model showing properly
here is my code,
for controller
$commision_arr=$this->billing_model->root_commision($category_manager['id']);
and in the model
public function root_commision($id)
{
$sql="SELECT * FROM tbl_mst_category WHERE id = '".$id."'";
$query = $this->db->query($sql);
$row=$query->row_array();
if($row['parent']!=0)
{
$this->root_commision($row['parent']);
}
else
return $row;
}
recursion is tricky huh?
i think the problem is that you were only returning the id for the deepest element, but not returning that to the calling method -- so it would only work for the case where the parent id was called. i can't test the code below, but it should point you in the right direction. NB, it returns the row as an object, not as an array as your code does.
On a more academic note, if the table is large it may be better to pre-calculate these root ids for each of these categories. it will make the query much faster -- recursion is not fast. look at transitive closures
public function root_commision($id,$root_found = FALSE)
{
// returns FALSE if the id is not found, or the parent row.
$query = $this->db->get_where('tbl_mst_category', array('id' => $id));
if ($query->num_rows() > 0 )
{
$row = $query->first_row();
if (($row->parent ) != 0 )
{
return $this->root_commision($row_id);
}
else
{
return $row;
}
}
else
{
return FALSE;
}
}
you have to return function at the calling time then only you can get
the value of recursive function just add "return" keyword before function call.
public function root_commision($id)
{
$sql="SELECT * FROM tbl_mst_category WHERE id = '".$id."'";
$query = $this->db->query($sql);
$row=$query->row_array();
if($row['parent']!=0)
{
return $this->root_commision($row['parent']);
}
else
return $row;
}

SilverStripe Inheriting elements from a parent dataobject

I have set a field called Colour in Page.php and for any child I would like to grab the parent colour or loop through till it finds a parent that does have the colour field set.
I have a function below which seems to work in 2.4 but I cannot get to work in SS3 which I call inside a loop in templates as $Inherited(Colour).
Your help is appreciated
public function Inherited($objName) {
$page = $this->owner->Data();
do {
if ($obj = $page->obj($objName)) {
if ($obj instanceof ComponentSet) {
if ($obj->Count()) {
return $obj;
}
} elseif ($obj instanceof DataObject) {
if ($obj->exists()) {
return $obj;
}
} elseif ($obj->exists()) {
return $obj;
}
}
} while ($page->ParentID != 0 && $page = $page->Parent());
}
Assuming your Colour field is a database field and not a relationship to another data object, add the following method to your Page class.
public function getColour() {
// Try returning banners for this page
$colour = $this->getField('Colour');
if ( $colour ) {
return $colour;
}
// No colour for this page? Loop through the parents.
$parent = $this->Parent();
if ( $parent->ID ) {
return $parent->getColour();
}
// Still need a fallback position (handled by template)
return null;
}
If colour is a related data object you could do much the same thing but use the getComponent or getComponents method in place of getField in the code above. This should work on both Silverstripe version 2.4.x and 3.0.x.
This kind of operation, although useful, should probably be done sparingly or be heavily cached as it's recursive could conceivably happen on the majority of page loads, and change very infrequently.
i suppose you've had this function defined inside some DataObjectDecorator, as you're using $this->owner to refer to the current page.
there is no more DataObjectDecorator in SilverStripe 3 (see http://www.robertclarkson.net/2012/06/dataextension-class-replacing-dataobjectdecorator-silverstripe-3-0/) so there are two possible solutions:
a) replace DataObjectDecorator by DataExtension
b) simply move the Inherited function to your Page class, and replace $this->owner by $this

Boolean in a URI query?

What is the preferred way to specify boolean value in the query part of URI? A normal query string looks like
a=foo&b=bar
Say I have a parameter "c" with boolean value, should I state
a=foo&b=bar&c=1
Or
a=foo&b=bar&c=True
Or
a=foo&b=bar&c=true
I checked the query component section of RFC 2396 and it does not specify how to express a boolean parameter. So what I want to know is what is the common (or reasonable) way to do it?
It completely depends on the way you read the query string. All of these that you ask for are valid.
Use key existence for boolean parameter like ?foo
For example, use ?foo instead of ?foo=true.
I prefer this way because I don't need to waste time to think or trace the source code about whether it should be true or 1 or enable or yes or anything that beyond my imagination.
In the case of case sensitivity, should it be true or True or TRUE?
In the case of term stemming, should it be enable or enabled?
IMHO, the form of ?foo is the most elegant way to pass a boolean variable to server because there are only 2 state of it (exist or not exist), which is good for representing a boolean variable.
This is also how Elasticsearch implemented for boolean query parameter, for example:
GET _cat/master?v
In node with an express server, you can add a boolean parser middleware like express-query-boolean.
var boolParser = require('express-query-boolean');
// [...]
app.use(bodyParser.json());
app.use(boolParser());
Without
// ?a=true&b[c]=false
console.log(req.query);
// => { a: 'true', b: { c: 'false' } }
With
// ?a=true&b[c]=false
console.log(req.query);
// => { a: true, b: { c: false } }
Url are strings and all values in a URL are strings,
all the params will be returned as strings.
it depends on how you interpret it in your code.
for the last one where c = true
you can do a JSON.parse(c)
which will change it to a boolean.
Also, you have to be careful not to pass it an empty string, if not it will throw an error.
I managed this with a custom function.
See browser compatibility here: https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams
function parseQuery(url = window.location.search) {
const urlParams = new URLSearchParams(url);
return Array.from(urlParams.keys()).reduce((acc, key) => {
const value = urlParams.get(key);
if (value) {
switch (value) {
case 'false': {
acc[key] = false;
break;
}
case 'true': {
acc[key] = true;
break;
}
case 'undefined': {
acc[key] = undefined;
break;
}
case 'null': {
acc[key] = null;
break;
}
default: {
acc[key] = value;
}
}
}
return acc;
}, {});
}
The function returns an object with all the parsed query parameters and fallback by default to the original value.
Or you can do this
const queryBool = unwrapTextBoolean({{{A_WAY_TO_GET_THAT_TEXT_BOOLEAN}}})
if(queryBool===null) {return;}
if(queryBool){
/*true-based code*/
}else{
/*false-based code*/
}
function unwrapTextBoolean(tB){
if(tB === 'true') return true;
if(tb === 'false') return false;
return null;
}

Can I get some advice on JavaScript delegates?

I'm rusty with delegates and closures in JavaScript, and think I came across a situation where I'd like to try to use one or both.
I have a web app that behaves a lot like a forms app, with fields hitting a server to change data on every onBlur or onChange (depending on the form element). I use ASP.NET 3.5's Web Services and jQuery to do most of the work.
What you need to know for the example:
isBlocking() is a simple mechanism to form some functions to be synchronous (like a mutex)
isDirty(el) checks to make sure the value of the element actually changed before wasting a call to the server
Agent() returns a singleton instance of the WebService proxy class
getApplicationState() passes a base-64 encoded string to the web service. This string represents the state of the application -- the value of the element and the state are passed to a service that does some calculations. The onSuccess function of the web service call returns the new state, which the client processes and updates the entire screen.
waitForCallback() sets a flag that isBlocking() checks for the mutex
Here's an example of one of about 50 very similar functions:
function Field1_Changed(el) {
if (isBlocking()) return false;
if (isDirty(el)) {
Agent().Field1_Changed($j(el).val(), getApplicationState());
waitForCallback();
}
}
The big problem is that the Agent().Field_X_Changed methods can accept a different number of parameters, but it's usually just the value and the state. So, writing these functions gets repetitive. I have done this so far to try out using delegates:
function Field_Changed(el, updateFunction, checkForDirty) {
if (isBlocking()) return false;
var isDirty = true; // assume true
if (checkForDirty === true) {
isDirty = IsDirty(el);
}
if (isDirty) {
updateFunction(el);
waitForCallback();
}
}
function Field1_Changed(el) {
Field_Changed(el, function(el) {
Agent().Field1_Changed($j(el).val(), getTransactionState());
}, true);
}
This is ok, but sometimes I could have many parameters:
...
Agent().Field2_Changed($j(el).val(), index, count, getApplicationState());
....
What I'd ultimately like to do is make one-linen calls, something like this (notice no getTransactionState() calls -- I would like that automated somehow):
// Typical case: 1 value parameter
function Field1_Changed(el) {
Field_Changed(el, delegate(Agent().Field1_Changed, $j(el).val()), true);
}
// Rare case: multiple value parameters
function Field2_Changed(el, index, count) {
Field_Changed(el, delegate(Agent().Field1_Changed, $j(el).val(), index, count), true);
}
function Field_Changed(el, theDelegate, checkIsDirty) {
???
}
function delegate(method) {
/* create the change delegate */
???
}
Ok, my first question is: Is this all worth it? Is this harder to read but easier to maintain or the other way around? This is a pretty good undertaking, so I may end up putting a bounty on this one, but I'd appreciate any help you could offer. Thanks!
UPDATE
So, I've accepted an answer based on the fact that it pointed me in the right direction. I thought I'd come back and post my solution so that others who may just be starting out with delegates have something to model from. I'm also posting it to see if anybody wants to try an optimize it or make suggestions. Here's the common Field_Changed() method I came up with, with checkForDirty and omitState being optional parameters:
function Field_Changed(el, args, delegate, checkForDirty, omitState) {
if (isBlocking()) return false;
if (!$j.isArray(args) || args.length == 0) {
alert('The "args" parameter in Field_Changed() must be an array.');
return false;
}
checkForDirty = checkForDirty || true; // assume true if not passed
var isDirty = true; // assume true for updates that don't require this check
if (checkForDirty === true) {
isDirty = fieldIsDirty(el);
}
if (isDirty) {
omitState = omitState || false; // assume false if not passed
if (!omitState) {
var state = getTransactionState();
args.push(state);
}
delegate.apply(this, args);
waitForCallback();
}
}
It handles everything I need it to (check for dirty, applying the application state when I need it to, and forcing synchronous webservice calls. I use it like this:
function TransactionAmount_Changed(el) {
Field_Changed(el, [cleanDigits($j(el).val())], Agent().TransactionAmount_Changed, true);
}
cleanDigits strips out junk characters the user may have tried to type in. So, thanks to everyone, and happy coding!
OK, few things:
Delegates are extremely simple in javascript since functions are first class members.
Function.apply lets you call a function with an array of arguments.
So you can write it this way
function Field_Changed(delegate, args)
{
if (isBlocking()) return false;
if (isDirty(args[0])) { //args[0] is el
delegate.apply(this, args);
waitForCallback();
}
}
And call it as:
Field_Changed(Agent().Field2_Changed, [el, getApplicationState(), whatever...]);
I have been using the following utility function that I wrote a long time ago:
/**
* #classDescription This class contains different utility functions
*/
function Utils()
{}
/**
* This method returns a delegate function closure that will call
* targetMethod on targetObject with specified arguments and with
* arguments specified by the caller of this delegate
*
* #param {Object} targetObj - the object to call the method on
* #param {Object} targetMethod - the method to call on the object
* #param {Object} [arg1] - optional argument 1
* #param {Object} [arg2] - optional argument 2
* #param {Object} [arg3] - optional argument 3
*/
Utils.createDelegate = function( targetObj, targetMethod, arg1, arg2, arg3 )
{
// Create an array containing the arguments
var initArgs = new Array();
// Skip the first two arguments as they are the target object and method
for( var i = 2; i < arguments.length; ++i )
{
initArgs.push( arguments[i] );
}
// Return the closure
return function()
{
// Add the initial arguments of the delegate
var args = initArgs.slice(0);
// Add the actual arguments specified by the call to this list
for( var i = 0; i < arguments.length; ++i )
{
args.push( arguments[i] );
}
return targetMethod.apply( targetObj, args );
};
}
So, in your example, I would replace
function Field1_Changed(el) {
Field_Changed(el, delegate(Agent().Field1_Changed, $j(el).val()), true);
}
With something along the lines
function Field1_Changed(el) {
Field_Changed(el, Utils.createDelegate(Agent(), Agent().Field1_Changed, $j(el).val()), true);
}
Then, inside of Agent().FieldX_Changed I would manually call getApplicationState() (and encapsulate that logic into a generic method to process field changes that all of the Agent().FieldX_Changed methods would internally call).
Closures and delegates in JavaScript:
http://www.terrainformatica.com/2006/08/delegates-in-javascript/
http://www.terrainformatica.com/2006/08/delegates-in-javascript-now-with-parameters/

Resources