I have a audio player and its pulling its audio from a folder its currently being sorted by name but I want to sort it by date created. any help would be appreciated.
$media = array();
$di = new DirectoryIterator($dir);
foreach ($di as $fileinfo) {
$path_info = pathinfo($fileinfo->getPathname());
if(isset($path_info['extension'])){
if(in_array(strtolower($path_info['extension']), $allowed_files)){
$fn = $fileinfo->getPathname();
$media[] = array(
"SITE_URL" => SITE_URL,
"SITEPATH" => SITEPATH,
"fullpath" => SITE_URL.'/'.path2url(realpath($path_info['dirname'])).'/'.$path_info['basename'],
"basename" => $path_info['basename'],
"extension" => $path_info['extension'],
"dirname" => realpath($path_info['dirname']),
"filename" => $path_info['filename']
);
}
}
DirectoryIterator only gives access to access Time, modification time or inode change time. If your files have not been changed since creation, modification time will be the same and you can then save that time in the $media array and then sort the array using array_multisort:
$media = array();
$di = new DirectoryIterator($dir);
foreach ($di as $fileinfo) {
$path_info = pathinfo($fileinfo->getPathname());
if(isset($path_info['extension'])){
if(in_array(strtolower($path_info['extension']), $allowed_files)){
$fn = $fileinfo->getPathname();
$media[] = array(
"SITE_URL" => SITE_URL,
"SITEPATH" => SITEPATH,
"fullpath" => SITE_URL.'/'.path2url(realpath($path_info['dirname'])).'/'.$path_info['basename'],
"basename" => $path_info['basename'],
"extension" => $path_info['extension'],
"dirname" => realpath($path_info['dirname']),
"filename" => $path_info['filename'],
"mtime" => $fileinfo->getMTime()
);
}
}
}
array_multisort(array_column($media, 'mtime'), SORT_ASC, $media);
Related
I have a varying array for a playlist, containing media/source URLs for each item. Like this:
$playlist = array(
array(
"title" => "something",
"sources" => array(
array(
"file" => "https://url.somedomain.com/path/file1.mp3"
)
),
"description" => "somedesc",
"image" => "http://imagepath/",
"file" => "https://url.somedomain.com/path/file1.mp3"
),
array(
"title" => "elsewaa",
"sources" => array(
array(
"file" => "https://url.somedomain.com/someother/file2.mp3"
)
),
"description" => "anotherdesc",
"image" => "http://someotherimagepath/",
"file" => "https://url.somedomain.com/someother/file2.mp3"
)
);
How do I find and replace the values in the file keys to 'randomise' the choice of subdomain?
For example, if the file key contains url.foo.com, how do I replace the url.foo.com portion of the array value with either differentsubdomain.foo.com or anotherplace.foo.com or someotherplace.foo.com?
I was kindly offered a solution for a single string in this question/answer that used str_replace (thanks Qirel!), but I need a solution that tackles the above array configuration specifically.
All the nesting in the array does my head in!
Is it possible to adapt Qirel's suggestion somehow?
$random_values = ['differentsubdomain.foo.com', 'anotherplace.foo.com', 'someotherplace.foo.com'];
$random = $random_values[array_rand($random_values)];
// str_replace('url.foo.com', $random, $file);
If you are just asking how to access members in nested arrays, I think you want this:
$random_values = ['differentsubdomain.foo.com', 'anotherplace.foo.com', 'someotherplace.foo.com'];
// Iterate through the array, altering the items by reference.
foreach ($playlist as &$item) {
$random_key = array_rand($random_values);
$new_domain = $random_values[$random_key];
$item['file'] = str_replace('url.foo.com', $new_domain);
$item['sources'][0]['file'] = str_replace('url.foo.com', $new_domain);
}
Here's an example using recursion to replace the subdomains in any keys named file with a random one.
function replaceUrlHost(&$array, $hostDomain, $subdomains)
{
foreach ($array as $key => $value) {
if (is_array($value)) {
$array[$key] = replaceUrlHost($value, $hostDomain, $subdomains);
continue;
}
if ($key !== 'file') {
continue;
}
$hostname = parse_url($value, PHP_URL_HOST);
if (strpos($hostname, $hostDomain) === false) {
continue;
}
$array[$key] = str_replace(
$hostname,
$subdomains[array_rand($subdomains)] . '.' . $hostDomain,
$value
);
}
return $array;
}
// usage
$subdomains = ['bar', 'baz', 'bing', 'bop'];
$out = replaceUrlHost($playlist, 'somedomain.com', $subdomains);
What's My Problem?
I am trying to use RecursiveDirectoryIterator Function in place of Scandir but not getting the required Json response.
I know this is a bit long piece of code but i really want to implement other features like directory permissions ,owner etc using iterator If someone can have a look at this i ll be very much thankful.
$path = dirname(__DIR__).'/files';
$dirname = explode('/',$path);
$dirname = end($dirname);
Scan Dir Function:
function scan($path,$dirname){
$files = array();
// Is there actually such a folder/file?
if(file_exists($path)){
foreach(scandir($path) as $f) {
if(!$f || $f[0] == '.') {
continue; // Ignore hidden files
}
$ext_to_exclude = array('php','html','.htacces');
if(cmprExtension($f,$ext_to_exclude)) {
continue; // Ignore some extensions
}
if(is_dir($path . '/' . $f)) {
// The path is a folder
$files[] = array(
"name" => $f,
"type" => "folder",
"path" => $dirname.'/'.$f,
"items" => scan($path.'/'.$f, $dirname.'/'.$f) // Recursively get the contents of the folder
);
}
else {
// It is a file
$files[] = array(
"name" => $f,
"type" => "file",
"path" => $dirname.'/'.$f,
"size" => filesize($path.'/'.$f) // Gets the size of this file
);
}
}
}
return $files;
}
RecursiveDirectoryiterator Function:
function scanRDI($path){
$rii = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::SKIP_DOTS));
$files = array();
foreach ($rii as $file){
if($file->isDir()) {
// The path is a folder
$files[] = array(
"name" => $file->getFilename(),
"type" => "folder",
"path" => $file->getPathname(),
"items" => scanRDI($file->getPath())
);
}
else {
// It is a file
$files[] = array(
"name" => $file->getFilename(),
"type" => "file",
"path" => $file->getPathname(),
"size" => $file->getSize() // Gets the size of this file
);
}
}
return $files;
}
Json Endoing:
header('Content-type: application/json');
echo json_encode(array(
"name" => $dirname,
"type" => "folder",
"path" => $dirname,
"items" => scan($path) OR scanRDI($path)
));
Json responses:(In jsonviewer change view to code from Right panel)
For Scandir : https://codebeautify.org/jsonviewer/cb94493e
For RDI : https://codebeautify.org/jsonviewer/cb9e1297
Using this lib uploading works great. I have number of objects in an excel and I go through them and do whatever I desire.
The question is while uploading the excel I am ought to check whether a particular object already exists, if so increment the $rejected variable otherwise create and increment the $uploaded variable. As a result I would like to return the results: how many uploaded and how many rejected? Whats the best way to do as such? It is obvious I can't access those variables inside the function. What's the best practice here?
public function uploadUsingFile($file)
{
$rejected = 0;
$uploaded = 0;
Excel::load($file, function ($reader) {
foreach ($reader->toArray() as $row)
{
$plateAlreadyExist = Plate::where('serial_number', $row['plate_serial_number'])->exists();
if ($plateAlreadyExist) {
$rejected += 1;continue;
}
$supplier = Supplier::firstOrCreate(['name' => $row['supplier_name']]);
$statusName = EquipmentStatusCode::firstOrCreate(['name' => $row['status_name']]);
$plateType = PlateType::firstOrCreate(['name' => $row['plate_type_name']]);
$process = Process::firstOrCreate(['name' => $row['process_name']]);
$project = Project::firstOrCreate(['name' => $row['project_name']]);
$plateQuality = PlateQuality::firstOrCreate(['name' => $row['plate_quality']]);
$wafer = Wafer::firstOrCreate(['serial_number' => $row['wafer_serial_number']]);
$data = [
'serial_number' => $row['plate_serial_number'],
'crc_code' => $row['crc_code'],
'supplier_id' => $supplier['id'],
'equipment_status_code_id' => $statusName['id'],
'plate_type_id' => $plateType['id'],
'process_id' => $process['id'],
'project_id' => $project['id'],
'plate_quality_id' => $plateQuality['id'],
'wafer_id' => $wafer['id'],
'created_by' => Auth::user()->id,
];
if($data)
{
Plate::create($data);
$uploaded += 1;
}
}
});
return [ 'uploaded' => $uploaded, 'rejected' => $rejected ];
}
You can pass a reference to the variables into the closure by using the use keyword:
...
Excel::load($file, function ($reader) use(&$rejected, &$uploaded){
...
}
Anonymous Functions
I'm using the code below to sort the content of my XML file by "WebCategory". My question is how do I save the newly sorted $products array back to the XML file?
<?php
$products = array();
$xml = simplexml_load_file('nwgalaxy-edited.xml');
foreach($xml->Product as $item) {
$products[] = array(
'ProductID' => (string)$item->attributes()->ProductID,
'Description' => (string)$item->Description,
'WebCategory' => (string)$item->WebCategory,
'WebSubCategory' => (string)$item->WebSubCategory,
'WebSubCat2' => (string)$item->WebSubCat2,
'QtyOnHand' => intval($item->QtyOnHand),
'SellingPrice' => intval($item->SellingPrice),
'ListPrice' => intval($item->ListPrice),
'NWGalaxy' => intval($item->NWGalaxy),
'UPC' => intval($item->UPC),
'VendorProductID' => (string)$item->VendorProductID,
'ImageSmall' => (string)$item->ImageSmall,
'ImageLarge' => (string)$item->ImageLarge
);
}
array_sort_by_column($products, 'WebCategory');
function array_sort_by_column(&$array, $column, $direction = SORT_ASC) {
$reference_array = array();
foreach($array as $key => $row) {
$reference_array[$key] = $row[$column];
}
array_multisort($reference_array, $direction, $array);
}
?>
This may work, not tested but should give general idea.
// Create tag products
$xml = new SimpleXMLElement('<products/>');
// Walk the array with callback to method $xml->addChild($this)
array_walk_recursive($products, array($xml, 'addChild'));
// Save generated content to file.
file_put_contents('nwgalaxy-edited.xml', $xml->asXML());
I'm iterating over a folder and formatting its contents in a certain way.
I've to form an array from this set of strings:
home--lists--country--create_a_country.jpg
home--lists--country--list_countries.jpg
profile--edit--account.jpg
profile--my_account.jpg
shop--orders--list_orders.jpg
The array needs to look like this:
<?php
array(
'home' => array(
'lists' => array(
'country' => array(
'create_a_country.jpg',
'list_countries.jpg'
)
)
),
'profile' => array(
'edit' => array(
'account.jpg'
),
'my_account.jpg'
),
'shop' => array(
'orders' => array(
'list_orders.jpg',
)
);
The thing is, the depth of the array could be infinitely deep depending on how many '--' dividers the file name has. Here's what I've tried (assuming each string is coming from an array:
$master_array = array();
foreach($files as $file)
{
// Get the extension
$file_bits = explode(".", $file);
$file_ext = strtolower(array_pop($file_bits));
$file_name_long = implode(".", $file_bits);
// Divide the filename by '--'
$file_name_bits = explode("--", $file_name_long);
// Set the file name
$file_name = array_pop($file_name_bits).".".$file_ext;
// Grab the depth and the folder name
foreach($file_name_bits as $depth => $folder)
{
// Create sub-arrays as the folder structure goes down with the depth
// If the sub-array already exists, don't recreate it
// Place $file_name in the lowest sub-array
// .. I'm lost
}
}
Can anyone shed some light on how I might do this? All insight appreciated.
w001y
Try this:
$files=array("home--lists--country--create_a_country.jpg","home--lists--country--list_countries.jpg","profile--edit--account.jpg","profile--my_account.jpg","shop--orders--list_orders.jpg");
$master_array=array();
foreach($files as $file)
{
$file=explode("--",$file);
$cache=end($file);
while($level=prev($file))
{
$cache=array($level=>$cache);
}
$master_array=array_merge_recursive($master_array,$cache);
}
print_r($master_array);
Live demo