We upload a lot of photos to WordPress. We do not use them all though. The unused ones remain "attached" to the post it's not in which makes it hard to go back and delete it.
I've build 2 arrays. One array contains all of the images from the post content ($postImages). The other array contains all of the images WordPress database have attached to the post ($mediaImages).
I'm trying to identify which images appear in the database, but not in the post. This way I can detach the image from within the database.
I'm using array_diff to compare the two arrays, however it's not showing the odd man out. It appears to be showing the matches.
Here's my arrays:
Call this one $postImages:
var_dump($postImages);
array(3) {
[2]=>
string(64) "http://mywebsite.com/wp-content/uploads/2013/11/photoblog1.jpg"
[0]=>
string(64) "http://mywebsite.com/wp-content/uploads/2013/11/photoblog2.jpg"
[1]=>
string(64) "http://mywebsite.com/wp-content/uploads/2013/11/photoblog3.jpg"
}
And $mediaImages:
var_dump($mediaImages);
array(4) {
[1]=>
array(1) {
[0]=>
string(64) "http://mywebsite.com/wp-content/uploads/2013/11/photoblog1.jpg"
}
[2]=>
array(1) {
[0]=>
string(64) "http://mywebsite.com/wp-content/uploads/2013/11/photoblog2.jpg"
}
[0]=>
array(1) {
[0]=>
string(64) "http://mywebsite.com/wp-content/uploads/2013/11/photoblog3.jpg"
}
[3]=>
array(1) {
[0]=>
string(62) "http://mywebsite.com/wp-content/uploads/2013/12/IMG_0069.jpg"
}
}
Here is the output:
$matches = array_diff($postImages, $mediaImages);
print_r($matches);
Array
(
[2] => http://mywebsite.com/wp-content/uploads/2013/11/photoblog1.jpg
[0] => http://mywebsite.com/wp-content/uploads/2013/11/photoblog2.jpg
[1] => http://mywebsite.com/wp-content/uploads/2013/11/photoblog3.jpg
)
Expected output:
Array
(
[0] => http://mywebsite.com/wp-content/uploads/2013/12/IMG_0069.jpg
)
As Marc B pointed out in the comments, $mediaImages is an array of arrays of strings, while $postimages is just an array of strings.
You can use array_map() with a custom callback to create the $mediaImages array:
$mediaImages = array_map(function($item) {
return $item[0];
}, $mediaImages);
Also, note that you have the parameters for array_diff() backwards. The correct order is:
array_diff($arrayToCompareFrom , $arrayToCompareAgainst);
So to compare $postImages against $mediaImages, you'd need:
$matches = array_diff($mediaImages, $postImages);
print_r($matches);
Demo.
Related
How to sort the following array?
I have an multidimensional array that gets filled with total hours for each brand
$totalHours = array(
'brand' => array(),
'project' => array(),
'hours' => array()
);
The output is something like this (project is not filled):
array(3) {
["brand"]=>
array(3) {
[0]=>
string(4) "Nike"
[1]=>
string(9) "Coke Cola"
[2]=>
string(8) "Converse"
}
["project"]=>
array(3) {
[0]=>
string(6) "Bonobo"
[1]=>
string(4) "LDRU"
[2]=>
string(2) "US"
}
["hours"]=>
array(3) {
[0]=>
int(28)
[1]=>
int(106)
[2]=>
string(1) "2"
}
}
Now I would like to sort the array based on the "hours" field.
I've tried the array_multisort but it seems like I simply don't get how this function works and how to apply it to this array.
I have been able to sort an single array with just one row of values. If I apply that to this problem im sorting only the hours field, leaving the others unsorted and therefore the array is corrupted.
The "project" does actually contains a string. It always does. In this example I didn't filled it.
array_multisort should work:
$totalHours = array(
'brand' => array('Nike', 'Coke Cola', 'Converse'),
'project' => array(),
'hours' => array(28, 106, '2')
);
array_multisort($totalHours['hours'], $totalHours['brand']);
var_dump($totalHours);
That data format is not very convenient because there is no direct association between brands and hours, they even sit in different arrays! Plus, the last hour is a string, not an integer.
We're going to have to create an intermediate array to associate them and sort them. We'll then re-inject everything in the original array.
// Make sure both arrays of brands and hours and the same size
if (count($totalHours['brand']) != count($totalHours['hours'])) {
throw new Exception('Invalid data!');
}
// Make sure every hour record is an integer, not a string
$totalHours['hours'] = array_map('intval', $totalHours['hours']);
// array_combine will sort all arrays based on the sorting of the first one
array_multisort($totalHours['hours'], $totalHours['brand'], $totalHours['project']);
EDIT: Using array_multisort was #delprks 's idea originally. Here I applied it to both brand and project arrays.
You cant do that with a single array_* function!
if (project is not filled) always and the indexes of brand and hours are equal, then you can do:
$forsort = array_combine($totalHours["brands"],$totalHours["hours"]);
asort($forsort,SORT_NUMERIC);
$totalHours["brands"]=array_keys($forsort);
$totalHours["hours"]=array_values($forsort);
But, this is just an answer for you question, not best practise at all.
I want to store 2 dependent values in this array:
["STEP5"]=> array(1) {
["OPTIONS"]=>
array(2) {
[0]=>
string(4) "opt2"
[1]=>
string(4) "opt3"
} }
Option fields (opt1, opt2,...) can have an extra field input. So how to store that in my array ? Thanx a lot.
You make each element of the OPTIONS array into an array itself. This would be better illustrated as:
["STEP5"] => array(1) {
["OPTIONS"] => array(2) {
[0] => array(2) {
["TEXT"] => "opt2"
["INPUT"] => "input data"
}
[1] => array(1) {
["TEXT"] => "opt3"
// No input data here
}
}
}
Then you can access the fields as:
$foo["STEP5"]["OPTIONS"][0]["TEXT"]
$foo["STEP5"]["OPTIONS"][0]["INPUT"]
$foo["STEP5"]["OPTIONS"][1]["TEXT"]
You don't have to have the "INPUT" field for every single option, but you can add it if you need to. Also, you might consider using objects to accomplish this task as they provide lots of useful functionality.
I'm trying to accomplish something very similar to what this user was doing Here.
I followed the answer, but I could not get it working. Inside the Active directory, my memberOf field looks like this:
CN=$VPN Users,CN=Users,DC=iai,DC=pri,CN=$ITAR,CN=Users,DC=iai,DC=pri,CN=allsubscribers,CN=Users,DC=iai,DC=pri
My Filter that works is:
(&(objectCategory=person)(sAMAccountName=$p_username))
I'm trying to get the following to work:
(&(objectCategory=person)(sAMAccountName=$p_username)(memberOf=CN=$ITAR))
I have tried adding the full DN which is
CN=Users,DC=iai,DC=pri
to my filter as well, but I get:
array(1) { ["count"]=> int(0) }
as my response.
I'm using ldap 3
This is the partial Working authentication code written in php:
$login = ldap_bind( $url, "username#somedomain", $password );
$attributes = array("displayname", "mailnickname");
$filter = "(&(objectCategory=person)(sAMAccountName=$username))";
$result = ldap_search($url, "CN=Users,DC=iai,DC=pri", $filter, $attributes);
$entries = ldap_get_entries($url, $result);
What am I doing wrong?
Code Result From #DaveRandom
First Var dump:
string(49) "(&(objectCategory=person)(sAMAccountName=rmoser))"
array(2) {
["count"] => int(1)
[0] => array(8) {
["displayname"] => array(2) {
["count"] => int(1)
[0] => string(10) "Ryan Moser"
}
[0] => string(11) "displayname"
["memberof"] => array(4) {
["count"] => int(3)
[0] => string(36) "CN=$VPN Users,CN=Users,DC=iai,DC=pri"
[1] => string(31) "CN=$ITAR,CN=Users,DC=iai,DC=pri"
[2] => string(40) "CN=allsubscribers,CN=Users,DC=iai,DC=pri"
}
[1]=> string(8) "memberof"
["mailnickname"] => array(2) {
["count"] => int(1)
[0] => string(6) "rmoser"
}
[2] => string(12) "mailnickname"
["count"] => int(3)
["dn"] => string(36) "CN=Ryan Moser,CN=Users,DC=iai,DC=pri"
}
}
bool(false)
Second var_dump:
string(70) "(&(objectCategory=person)(sAMAccountName=rmoser)(memberof=*CN=$ITAR*))"
array(1) {
["count"] => int(0)
}
LDAP filters look for an exact match.
In order to match CN=$ITAR anywhere in a value, you will need to surround it with the filter wildcard character *.
Try this filter:
(&(objectCategory=person)(sAMAccountName=$p_username)(memberOf=*CN=$ITAR*))
Also don't forget that $ITAR is a valid variable name in PHP, so if you place that filter string in double quotes (which you would need to in order for $p_username to be interpolated) PHP will attempt to interpolate $ITAR as a variable as well, find that it (probably) doesn't exist and the end result will be that it gets stripped from the string.
$filter = "(&(objectCategory=person)(sAMAccountName=$p_username)(memberOf=*CN=\$ITAR*))";
A useful link for any question concerning a dynamic filter built with PHP is this.
What is the best way to group and still maintain order with in groups?
I have an array full of directory paths to files. The array file paths are ordered by the files creation dates.
I want to keep the files in order of creation date but also group them in order of what directory they are in.
Example:
array() {
[1]=> "media/abstract/safe.png"
[2]=> "media/urban/Cross Street 2.png"
[4]=> "media/urban/The Other Side.png"
[5]=> "media/urban/Pharm Child.png"
[6]=> "media/food/DSC_3017.png"
[7]=> "media/abstract/fractal_twins.png"
[9]=> "media/urban/Amsterdam.png"
[11]=> "media/nature/creep.png"
[12]=> "media/urban/obstructed.png"
[13]=> "media/nature/middletown_dreams.png"
}
reordered would look like:
array() {
[1]=> "media/abstract/safe.png"
[2]=> "media/abstract/fractal_twins.png"
[3]=> "media/food/DSC_3017.png"
[4]=> "media/nature/creep.png"
[5]=> "media/nature/middletown_dreams.png"
[6]=> "media/urban/Cross Street 2.png"
[7]=> "media/urban/The Other Side.png"
[8]=> "media/urban/Pharm Child.png"
[9]=> "media/urban/Amsterdam.png"
[10]=> "media/urban/obstructed.png"
}
They are now grouped by their directories, but within their directories they maintain their order relative to one another.
It's not quite straightforward because all of the PHP sorting functions sort by only key or value (as far as I know). But the information needed is in both the key and value. So you'll need to modify the array first, then sort, then change it back to just have the file names.
function sort_files(array &$files)
{
/* add extended info:
0: index (original order)
1: dir name
2: original file name */
$i = 0;
$files = array_map(function($name) use (&$i) {
return array($i++, dirname($name), $name);
}, $files);
/* sort extended array by dir then index */
usort($files, function($a, $b) {
$cmp = strcmp($a[1], $b[1]);
if (!$cmp) $cmp = $a[0] - $b[0];
return $cmp;
});
/* remove extended info from array */
$files = array_map(function($a) {
return $a[2];
}, $files);
}
sort_files($files);
Output:
Array
(
[0] => media/abstract/safe.png
[1] => media/abstract/fractal_twins.png
[2] => media/food/DSC_3017.png
[3] => media/nature/creep.png
[4] => media/nature/middletown_dreams.png
[5] => media/urban/Cross Street 2.png
[6] => media/urban/The Other Side.png
[7] => media/urban/Pharm Child.png
[8] => media/urban/Amsterdam.png
[9] => media/urban/obstructed.png
)
I have the following array:
array(2) {
[0] => array(3) {
["submission_id"] => int(28)
["date"] => string(22) "2010-10-18 15:55:33+02"
["user_id"] => int(12)
}
[1] => array(3) {
["submission_id"] => int(37)
["date"] => string(22) "2010-11-21 16:02:07+01"
["user_id"] => int(23)
}
I want to get only the user_id key values from this array. I could obviously loop over it, but I was wondering if there was a quicker way.
You could use array_map (might not be quicker though, as it will make a function call per array element):
function getUserId($a) {
return $a['user_id'];
}
$user_ids = array_map('getUserId', $array);
Apart from that, looping is the only way (array_map makes loop anyway).
You can access only the user_id values like this if you know the array index you want to access:
$arr = your array here..
echo $arr[0]['user_id'];
echo $arr[1]['user_id'];