Doctrine Repository accept array for getAll - php

In a repository, I need a custom getALL query which checks for items based on an array of data. e.g. I need to be able to send $params = [ 'type' => [ 'type1', 'type2' ], 'username' => $username ] but I can currently only send one parameter such as: $params = ['type' => 'type1', 'username' => $username].
What would be the best way of adding acceptance of an array (like the one above) to this getAll query?:
public function getAllQuery($params = [])
{
$query = $this->createQueryBuilder('c');
if(count($params))
{
foreach($params as $param => $value)
{
//todo need to make it accept an array of parameters
if(in_array($param, $this->getClassMetadata()->getFieldNames()) && $param != 'deleted')
{
$query
->andWhere(sprintf('c.%1$s LIKE :%1$s', $param))
->setParameter($param, sprintf('%%%s%%', $value));
}
/*code already exists here for checking other parameters
outside of 'type' (e.g. 'username') */
}
}
return $query->getQuery();
}

I am not able to comment so I will answer without to be sur that I've understand the question. Are you waiting something like this ? In this case it's more a PHP problem than Doctrine.
The results of the past code : here.
$params = array( 'type' => array( 'type1', 'type2' ), 'username' => 'flavien');
$requiredFields = array('type');
if(count($params))
{
foreach($params as $param => $value)
{
if(in_array($param, $requiredFields) && $param != 'deleted')
{
if(is_array($value))
{
echo "My param: {$param}" . PHP_EOL;
for($i=0; $i < count($value); $i++) {
echo $value[$i] . PHP_EOL;
}
}
}
}
}

Related

Can I make a if-else statement based on a array?

Here is my current code:
if ( by == 'id') {
handlePromises(identifier_websites)
} else if ( by == 'name'){
handlePromises(names_websites)
} else if ( by == 'email' ) {
handlePromises(email_websites)
} else if ( by == 'phone' ) {
handlePromises(phone_websites)
}
Now I want to make it a little bit more modular (functional). I mean, I want to make the whole code above based on an array like this:
$parts = ['id', 'name', 'email', 'phone'];
So if I add one item to that array, then automatically a else if block should be added to the code based on that item .
Is doing that possible?
Not sure if I get you but here's how you can automate the above slightly.
$parts = [
'id' => identifier_websites,
'name' => names_websites,
'email' => emails_websites,
'phone' => phone_websites
];
foreach ($parts as $cond => $params) {
if (by == $cond) {
handlePromises($params);
break;
}
}

Dynamically dig into JSON with PHP

Okay, so I need to dynamically dig into a JSON structure with PHP and I don't even know if it is possible.
So, let's say that my JSON is stored ad the variable $data:
$data = {
'actions':{
'bla': 'value_actionBla',
'blo': 'value_actionBlo',
}
}
So, to access the value of value_actionsBla, I just do $data['actions']['bla']. Simple enough.
My JSON is dynamically generated, and the next time, it is like this:
$data = {
'actions':{
'bla': 'value_actionBla',
'blo': 'value_actionBlo',
'bli':{
'new': 'value_new'
}
}
}
Once again, to get the new_value, I do: $data['actions']['bli']['new'].
I guess you see the issue.
If I need to dig two levels, then I need to write $data['first_level']['second_level'], with three, it will be $data['first_level']['second_level']['third_level'] and so on ...
Is there any way to perform such actions dynamically? (given I know the keys)
EDIT_0: Here is an example of how I do it so far (in a not dynamic way, with 2 levels)
// For example, assert that 'value_actionsBla' == $data['actions']['bla']
foreach($data as $expected => $value) {
$this->assertEquals($expected, $data[$value[0]][$value[1]]);
}
EDIT_1
I have made a recursive function to do it, based on the solution of #Matei Mihai:
private function _isValueWhereItSupposedToBe($supposedPlace, $value, $data){
foreach ($supposedPlace as $index => $item) {
if(($data = $data[$item]) == $value)
return true;
if(is_array($item))
$this->_isValueWhereItSupposedToBe($item, $value, $data);
}
return false;
}
public function testValue(){
$searched = 'Found';
$data = array(
'actions' => array(
'abort' => '/abort',
'next' => '/next'
),
'form' => array(
'title' => 'Found'
)
);
$this->assertTrue($this->_isValueWhereItSupposedToBe(array('form', 'title'), $searched, $data));
}
You can use a recursive function:
function array_search_by_key_recursive($needle, $haystack)
{
foreach ($haystack as $key => $value) {
if ($key === $needle) {
return $value;
}
if (is_array($value) && ($result = array_search_by_key_recursive($needle, $value)) !== false) {
return $result;
}
}
return false;
}
$arr = ['test' => 'test', 'test1' => ['test2' => 'test2']];
var_dump(array_search_by_key_recursive('test2', $arr));
The result is string(5) "test2"
You could use a function like this to traverse down an array recursively (given you know all the keys for the value you want to access!):
function array_get_nested_value($data, array $keys) {
if (empty($keys)) {
return $data;
}
$current = array_shift($keys);
if (!is_array($data) || !isset($data[$current])) {
// key does not exist or $data does not contain an array
// you could also throw an exception here
return null;
}
return array_get_nested_value($data[$current], $keys);
}
Use it like this:
$array = [
'test1' => [
'foo' => [
'hello' => 123
]
],
'test2' => 'bar'
];
array_get_nested_value($array, ['test1', 'foo', 'hello']); // will return 123

PHP - Arrays and Foreach

I searched in Google and consulted the PHP documentation, but couldn't figure out how the following code works:
$some='name=Licensing Module;nextduedate=2013-04-10;status=Active|name=Test Addon;nextduedate=2013-04-11;status=Active';
function getActiveAddons($somet) {
$addons = array( );
foreach ($somet as $addon) {
if ($addon['status'] == 'Active') {
$addons[] = $addon['name'];
continue;
}
}
return $addons;
}
echo (count( getActiveAddons( $some ) ) ? implode( '<br />', getActiveAddons( $some ) ) : 'None');
The code always echo's None.
Please help me in this.
I don't know where you got this code from but you've initialized $some the wrong way. It is expected as an array like this:
$some = array(
array(
'name' => 'Licensing Module',
'nextduedate' => '2013-04-10',
'status' => 'Active'
),
array(
'name' => 'Test Addon'
'nextduedate' => '2013-04-11',
'status' => 'Active'
)
);
I guess the article you've read is expecting you to parse the original string into this format.
You can achieve this like this:
$string = 'name=Licensing Module;nextduedate=2013-04-10;status=Active|name=Test Addon;nextduedate=2013-04-11;status=Active';
$result = array();
foreach(explode('|', $string) as $record) {
$item = array();
foreach(explode(';', $record) as $column) {
$keyval = explode('=', $column);
$item[$keyval[0]] = $keyval[1];
}
$result[]= $item;
}
// now call your function
getActiveAddons($result);
$some is not an array so foreach will not operate on it. You need to do something like
$some = array(
array(
'name' => 'Licensing Module',
'nextduedate' => '2013-04-10',
'status' => 'Active'
),
array(
'name' => 'Test Addon',
'nextduedate' => '2013-04-11',
'status'=> 'Active'
)
);
This will create a multidimensional array that you can loop through.
function getActiveAddons($somet) {
$addons = array( );
foreach ($somet as $addon) {
foreach($addon as $key => $value) {
if ($key == 'status' && $value == 'Active') {
$addons[] = $addon['name'];
continue;
}
}
}
return $addons;
}
First, your $some variable is just a string. You could parse the string into an array using explode(), but it's easier to just start as an array:
$some = array(
array(
"name" => "Licensing Module",
"nextduedate" => "2013-04-10",
"status" => "Active",
),
array(
"name" => "Test Addon",
"nextduedate" => "2013-04-11",
"status" => "Active",
)
);
Now, for your function, you are on the right track, but I'll just clean it up:
function getActiveAddons($somet) {
if (!is_array($somet)) {
return false;
}
$addons = array();
foreach ($somet as $addon) {
if ($addon['status'] == 'Active') {
$addons[] = $addon['name'];
}
}
if (count($addons) > 0) {
return $addons;
}
return false;
}
And finally your output (you were calling the function twice):
$result = getActiveAddons($some);
if ($result === false) {
echo "No active addons!";
}
else {
echo implode("<br />", $result);
}

Php Array key=> value searching

HI I am fairly new to php.
I have an array
$arr = array(0 => array('GID'=>1,'groupname'=>"cat1",'members'=>array(0=>array('mid'=>11,'mname'=>'wwww'),1=>array('mid'=>12,'mname'=>'wswww'))),
1 => array('GID'=>2,'groupname'=>"cat2",'members'=>array(0=>array('mid'=>13,'mname'=>'gggwwww'),1=>array('mid'=>14,'mname'=>'wvvwww'))),
2 => array('GID'=>3,'groupname'=>"cat1",'members'=>array(0=>array('mid'=>15,'mname'=>'wwddsww')),1=>array('mid'=>16,'mname'=>'wwwdddw')));
ie...,I have GID,groupname,mid(member id),mname(member name).I want to insert a new mid and mname into a group if it is already in the array ,if it is not exists then create a new subarray with these elements..I also need to check a member id(mid) is also present.........................I used the code but its not working fine............. if (!empty($evntGroup)) {
foreach ($evntGroup as $k => $group) {
if ($group['GID'] == $group_id) {
foreach($group as $j=> $mem){
if($mem['mid'] == $mem_id){
unset($evntGroup[$k]['members'][$j]['mid']);
unset($evntGroup[$k]['members'][$j]['mname']);
}
else{
$evntGroup[$k]['members'][] = array(
'mid' => $mem_id,
'mname' => $mem_name);
}}
} else {
$evntGroup[] = array(
'GID' => $group_id,
'groupname' => $Group['event_group_name'],
'members' => array(
0 => array(
'mid' => $mem_id,
'mname' => $mem_name
)
)
);
}
}
} else {
$evntGroup[$i]['GID'] = $group_id;
$evntGroup[$i]['groupname'] = $Group['event_group_name'];
$evntGroup[$i]['members'][] = array(
'mid' => $mem_id,
'mname' => $mem_name);
$i++;
}
In the form of a function, the easiest solution will look something like this:
function isGidInArray($arr, $val) {
foreach($arr as $cur) {
if($cur['GID'] == $val)
return true;
}
return false;
}
You've updated your question to specify what you want to do if the specified GID is found, but that's just a trivial addition to the loop:
function doSomethingIfGidInArray($arr, $val) {
foreach($arr as $cur) {
if($cur['GID'] == $val) {
doSomething();
break; //Assuming you only expect one instance of the passed value - stop searching after it's found
}
}
}
There is unfortunately no native PHP array function that will retrieve the same index of every array within a parent array. I've often wanted such a thing.
Something like this will match if GID equals 3:
foreach( $arr as $item ) {
if( $item['GID'] == 3 ) {
// matches
}
}
There is the code
function updateByGid(&$array,$gid,$groupname,$mid,$mname) {
//For each element of the array
foreach ($array as $ii => $elem) {
//If GID has the same value
if ($elem['GID'] == $gid) {
//Insert new member
$array[$ii]['members'][]=array(
'mid'=>$mid,
'mname'=>$mname);
//Found!
return 0;
}
}
//If not found, create new
$array[]=array(
'GID'=>$gid,
'groupname'=>$groupname,
'members'=>array(
0=>array(
'mid'=>$mid,
'mname'=>$mname
)
)
);
return 0;
}

How to invoke method by name?

I want to pass a row object to a function that uses the configuration information stored in the row to build a Zend Search Lucene Document and add it to my index.
The information stored looks like this:
protected $_index = array(
'url' => array('UnIndexed', 'getUrl()'),
'fragment' => array('UnIndexed', 'getFragment()'),
'edited' => array('UnIndexed', 'edited'),
'title' => array('Text', 'getTitle()'),
'summary' => array('Text', 'getSummary()'),
'text' => array('UnStored', 'getText()'),
);
Here's the function I call:
public static function addDoc(My_Db_Table_Row_Abstract $row)
{
$config = $row->getIndexConfig();
if (empty($config)) {
return;
}
// setup the document
$document = new Zend_Search_Lucene_Document();
$document->addField(Zend_Search_Lucene_Field::keyword('table_name', $row->getTable()->info('name')))
->addField(Zend_Search_Lucene_Field::keyword('table_row_key', $row->getIndexRowKey()));
// add the configured fields
foreach ($config as $name => $opts) {
$type = $opts[0];
$value = eval('return $row->' . $opts[1]);
switch ($type) {
case 'Keyword' :
$field = Zend_Search_Lucene_Field::keyword($name, $value);
break;
case 'UnIndexed' :
$field = Zend_Search_Lucene_Field::unIndexed($name, $value);
break;
case 'Binary' :
$field = Zend_Search_Lucene_Field::binary($name, $value);
break;
case 'Text' :
$field = Zend_Search_Lucene_Field::text($name, $value);
break;
case 'UnStored ' :
$field = Zend_Search_Lucene_Field::unStored($name, $value);
break;
}
$document->addField($field);
}
// add to the index
self::getIndex()->addDocument($document);
}
As you can see, I need to get information via function calls into the document fields. I am concerned about using eval(), but I don't know another way. Is there a better way to accomplish the same functionality?
SOLUTION
I changed the configuration data to use functions for all the fields (removing the parenthesis), and lower-cased the first letter of the type so I could use that for call_user_func as well:
protected $_index = array(
'url' => array('unIndexed', 'getUrl'),
'fragment' => array('unIndexed', 'getFragment'),
'edited' => array('unIndexed', 'getEdited'),
'active_self' => array('keyword', 'isActive'),
'active_block' => array('keyword', 'isActiveBlock'),
'active_page' => array('keyword', 'isActiveNav'),
'members_only' => array('keyword', 'isMembersOnly'),
'title' => array('text', 'getTitle'),
'summary' => array('text', 'getSummary'),
'text' => array('unStored', 'getText'),
);
And the function call, which ended up being much simpler:
public static function addDoc(My_Db_Table_Row_Abstract $row)
{
$config = $row->getIndexConfig();
if (empty($config)) {
return;
}
// setup the document
$document = new Zend_Search_Lucene_Document();
$document->addField(Zend_Search_Lucene_Field::keyword('table_name', $row->getTable()->info('name')))
->addField(Zend_Search_Lucene_Field::keyword('table_row_key', $row->getIndexRowKey()));
// add the configured fields
foreach ($config as $name => $opts) {
$value = call_user_func(array($row, $opts[1]));
$field = call_user_func(array('Zend_Search_Lucene_Field', $opts[0]), $name, $value);
$document->addField($field);
}
// add to the index
self::getIndex()->addDocument($document);
}
You can also use call_user_func. Here is the PHP doc.
Example:
<?php
function barber($type)
{
echo "You wanted a $type haircut, no problem\n";
}
call_user_func('barber', "mushroom");
call_user_func('barber', "shave");
?>
Output:
You wanted a mushroom haircut, no problem
You wanted a shave haircut, no problem
For you example, you need to change :
$value = eval('return $row->' . $opts[1]);
by
$value = call_user_func($row->' . $opts[1]);
I guess you can do:
// ...
$type = $opts[0];
$method = $opts[1];
$value = $row->$method;
Or:
// ...
$type = $opts[0];
call_user_func(array($row, $opts[1]));
Remove the parens from your method names:
protected $_index = array(
'url' => array('UnIndexed', 'getUrl'),
'fragment' => array('UnIndexed', 'getFragment'),
...
Replace this attribute:
'edited' => array('UnIndexed', 'edited'),
With an equivalent getter method:
'edited' => array('UnIndexed', 'getEdited'),
Then just do this:
$method = $opts[1];
$value = $row->$method();

Categories