Implode associative array with variable key name - php

I'm using an associative array to build a list of albums and the images inside those albums. The array is built with the following code (some code omitted for clarity -- just the stuff that loads $title, $desc, etc.):
<?php
$directory = 'gallery/*';
$subfolders = glob($directory);
foreach($subfolders as $subfolder) {
$photos = glob($subfolder.'/*.[Jj][Pp][Gg]');
$album = explode('_', $subfolder);
$albumname = str_replace(' ','%20',$album[1]);
foreach($photos as $photo){
$photolist[$albumname] .= '<span data-title="'.$title.'" data-desc="'.$desc.'" data-camera="'.$camera.'" data-lens="'.$lens.'" data-length="'.$length.'" data-shutter="'.$shutter.'" data-aperture="'.$aperture.'" data-iso="'.$iso.'" style="background-image:url('.$photo.'); background-size:contain;" class="slide"></span>';
}
}
?>
I'm trying to use implode() to spit out the relevant elements based on the $currentalbum (read from a cookie) as follows:
<?php
if(isset($_COOKIE["currentalbum"])) {
$currentalbum = $_COOKIE["currentalbum"];
} else {
$currentalbum = "New";
}
$currentphotolist = implode("",$photolist[$currentalbum]);
echo $currentphotolist;
?>
This is returning the error:
Warning: implode() [function.implode]: Invalid arguments passed in index.php on line 97
I presume it has some problem with the array, but when I print_r() it, I get the following, which looks fine:
Array
(
[New] => <span data-title="Train" data-desc="This is a picture of a train. Look at it go!" data-camera="Nikon D300" data-lens="Tamron 17-50mm f/2.8 VC" data-length="17mm" data-shutter="1/250s" data-aperture="f/6.3" data-iso="200" style="background-image:url(gallery/01_New/Train.jpg); background-size:contain;" class="slide"></span><span data-title="Billow" data-desc="" data-camera="Nikon D300" data-lens="Nikkor 50mm f/1.8D" data-length="50mm" data-shutter="1/250s" data-aperture="f/8" data-iso="200" style="background-image:url(gallery/01_New/Billow.jpg); background-size:contain;" class="slide"></span><span data-title="3059" data-desc="" data-camera="Nikon D300" data-lens="Micro-Nikkor 105mm f/2.8 VR" data-length="105mm" data-shutter="1/30s" data-aperture="f/22" data-iso="200" style="background-image:url(gallery/01_New/3059.jpg); background-size:contain;" class="slide"></span>
[Landscapes] => <span data-title="Influx" data-desc="" data-camera="Nikon D300" data-lens="Nikkor 70-300mm f/4.5-5.6 VR" data-length="70mm" data-shutter="30s" data-aperture="f/8" data-iso="200" style="background-image:url(gallery/02_Landscapes/Influx.jpg); background-size:contain;" class="slide"></span>
[Constructs] => <span data-title="Fervor" data-desc="I took this while wandering around in SEA-TAC airport waiting for a flight home. It\'s a lantern, hanging with some others in a shop. It caught my eye from across the terminal, but the shop was pretty small and I\'m always a little worried about knocking stuff with my camera bag, so I shot it through the window. I think it turned out pretty well regardless." data-camera="Nikon D7000" data-lens="Tamron 17-50mm f/2.8 VC" data-length="50mm" data-shutter="1/60s" data-aperture="f/2.8" data-iso="180" style="background-image:url(gallery/03_Constructs/Fervor.jpg); background-size:contain;" class="slide"></span>
)
Any idea why I'm getting the error?

The second argument to implode should be an array. It seems from your foreach loop that $photolist[$currentalbum] is a string.
Try
foreach($photos as $photo){
$photolist[$albumname][]= '<span data-title...</span>';
}

I believe implode requires a character as the first attribute. Try using a space or comma.
// Space
$currentphotolist = implode(" ",$photolist[$currentalbum]);
// Comma
$currentphotolist = implode(",",$photolist[$currentalbum]);

Related

Plugin preg_match_all Error after Updating from very oldto PHP 7.4 [duplicate]

This question already has an answer here:
PCRE2 Regex error escape sequence is invalid in character class
(1 answer)
Closed 2 years ago.
Our website with error turned on (plugin activated):
Example URLs with error:
https://www.live-karikaturen.ch/downloads/1-august-fahnen-schwingen-nationalfeiertag-schweiz/
https://www.live-karikaturen.ch/webshop-gratisbilder-free-cartoon-comic-images/
https://www.live-karikaturen.ch/downloads/auto-suv-autofan-abgase-umweltverschmutzung/
UPDATE INCOMPATIBILITY: I updated from a very old PHP version to 7.4
I use this EXTREMLY important plugin, which is horrible outdated (4 years last Update):
https://wordpress.org/support/plugin/creative-commons-configurator-1/
Now I get this error and I think it's maybe very easy to solve, but I know almost nothing about PHP, but I try to learn it a bit, so thank you very much in advance.
ERROR:
*
Warning: preg_match_all(): Compilation failed: escape sequence is
invalid in character class at offset 18 in
/home/clients/f9abb707fe4ac1215fe0f0a9c0b0ae21/www.live-karikaturen-ch/wp-content/plugins/creative-commons-configurator-1/creative-commons-configurator-1.php
on line 821
I copy the code from the .php file here
CODE:This is line 821:
if ( ! preg_match_all( $pattern_images_no_caption, $post_content, $matches ) ) {
return $post_content;
}
CODE From line 803 - 828 (don't know who to copy the line numbers):
function bccl_separate_licensing_on_images_without_caption( $post_content ) {
// Plugin options
$options = get_option('cc_settings');
if ( $options === false || $options['cc_enable_individual_media_licensing'] == '0' ) {
return $post_content;
}
$post = get_queried_object();
if ( apply_filters('bccl_exclude_license', false, $post) ) {
return $post_content;
}
// Pattern that matches images without caption
//$pattern_images_no_caption = '#<p>[\s\R]*(<img [^>]+>)#';
$pattern_images_no_caption = '#<(?:p|h[\d]+)>[\s\R]*(<img [^>]+>)#';
$pattern_images_no_caption = apply_filters('bccl_pattern_match_images_without_caption' , $pattern_images_no_caption);
**if ( ! preg_match_all( $pattern_images_no_caption, $post_content, $matches ) ) {
return $post_content;
}**
//var_dump($matches[1]);
// Iterate over the found images and add licensing metadata
foreach ( $matches[1] as $image_html ) {
Is there a simple way how to fix this error?
THANK YOU VERY MUCH FOR YOUR ANSWER & HELP!
THAAAANK you very much, you are AMAZING! :) I tried it out and it works, at least there is no error anymore.
FIRST
I am just not sure which version of the corrected code I should take. I guess Nr. 1 is ok, without []. That mean, as Toto wrote above I replaced [\s\R] with a simple \s.
Nr. 1.) without []
//$pattern_images_no_caption = '#\s*(<img [^>]+>)#';
$pattern_images_no_caption = '#<(?:p|h[\d]+)>\s*(<img [^>]+>)#';
Nr. 2.) with []
//$pattern_images_no_caption = '#<p>[\s]*(<img [^>]+>)#';
$pattern_images_no_caption = '#<(?:p|h[\d]+)>[\s]*(<img [^>]+>)#';
SECOND
I searched the whole creative-commons-configurator.php plugin code for \R and found further in line 979 this:
$parts = preg_split('#\R#u', $attach`enter code here`ment_data);
All lines together of this part are this:
// Attachment ID
// Unfortunately, WP does not provide enough information in order to determine the attachment ID
// So, first collect all the audio/video media file URLs in $attachments_urls
$attachments_data = get_post_meta( $post->ID, 'enclosure', false );
//var_dump($attachments_data);
$attachments_urls = array();
foreach ( $attachments_data as $attachment_data ) {
$parts = preg_split('#\R#u', $attachment_data);
$attachments_urls[] = $parts[0];
}
//var_dump($attachments_urls);
// Then check which media file URL exists in the $atts array so as to
// determine which attachment we are processing currently.
$atts_values = array_values($atts);
//var_dump($atts_values);
// Find the URL of the attachment we are processing
$current_attachment_url = '';
foreach ( $attachments_urls as $attachment_url) {
if ( in_array($attachment_url, $atts_values) ) {
$current_attachment_url = $attachment_url;
break;
}
}
QUESTION: In the moment I don't get any error, but I wonder if this will produce one and I have to delete or replace the "evil" \R?

PHP Scraper Loops Until Time Limit Exceeded (Using Simple HTML Dom Parser)

I am attempting to scrape the price of the same product from two different websites. While it pulls the correct results and prints out what I want, when the I run the script I get this error after the results are correctly printed:
Fatal error: Maximum execution time of 120 seconds exceeded in [...] on line 144
And this is my code:
<?php
//Adds in the simple HTML DOM parser
include ('simple_html_dom.php');
//Defines the Target URL to Scrape
$cbdUrl = "https://cbdstore.co.za/product/africanpure-everyday-cbd-1000mg-30ml/";
$apUrl = "https://africanpure.co/product/everyday-cbd-oil-1000mg-30ml/";
//Defines 'html' as the scraped content from the URL above
$cbdHtml = file_get_html($cbdUrl);
$apHtml = file_get_html($apUrl);
//Creating an array to store all the 'price' classes text from the page
$cbdPrices = array();
//Fetching all the '.amount' and storying them in the array as plain text.
foreach($cbdHtml->find('div.summary.entry-summary p.price') as $cbdElement)
{
foreach($cbdElement->find('.amount') as $cbdAmt)
{
$cbdPrices [] = $cbdAmt->plaintext;
}
}
//Repeating for AfricanPure
$apPrices = array();
foreach($apHtml->find('div.summary-inner div.basel-scroll-content p.price') as $apElement)
{
foreach($apElement->find('.amount') as $apAmt)
{
$apPrices [] = $apAmt->plaintext;
}
}
// Writes out CBD Store Price
echo 'CBD Store has the Everday CBD Oil for: ' . $cbdPrices[0];
// Writes out AP Price
echo 'African Pure has the Everday CBD Oil for: ' . $apPrices[0];
?>
It looks like you are only interested in one price for each ($cbdPrices[0]) and not an array of prices, so try breaking out of the loops after getting the first price.
foreach($cbdHtml->find('div.summary.entry-summary p.price') as $cbdElement)
{
foreach($cbdElement->find('.amount') as $cbdAmt)
{
$cbdPrices [] = $cbdAmt->plaintext;
break;
}
}
And do the same on the other one. You could also probably not make the variable an array in the first place?

PHP Processing stream_get_contents into an array

I am having troubles converting a string which contains tab delimited CSV output
into an array. While using the following code :
$data = stream_get_contents($request->getShipmentReport());
I get back data as following:
Date Shipped Comments Feedback Arrived on Time
5/11/15 2 comment response Yes
Now I would like to process this data into an array with the returned headers(line 1) as the index containing the value for each line which follows after that.
I am trying to end up with something like this :
$line['Date'] = 5/11/15
$line['Shipped'] = 2
$line['Feedback'] = response
$line['Arrived on Time'] yes
What would be the best way to achieve this ?
I recommend using a library for handling CSV for example the CSV-Package by The League of Extraordinary Packages
You can pass your data and start working with array structures right away:
$csvString = stream_get_contents($request->getShipmentReport());
$csvReader = \League\Csv\Reader::createFromString($csvString);
$data = $csvReader->fetchAssoc(
array('Date', 'Shipped', 'Comments', 'Feedback', 'Arrived on Time')
);
// Or since line 0 contains header
$data = $csvReader->fetchAssoc(0); // 0 is offset of dataset containing keys
Now your data should be in a structure like:
$data = array(
array(
'Date' => '5/11/15',
'Shipped' => '2',
...
),
array(
...
)
);
You can even filter out specific datasets and all kinds of fancy stuff. Just check the documentation I linked to.
League CSV reader gives me a bad result. I use this instead:
$csvReportString = stream_get_contents($request->getReport());
$csvReportRows = explode("\n", $csvReportString);
$report = [];
foreach ($csvReportRows as $c) {
var_dump($c);
if ($c) { $report[] = str_getcsv($c, "\t");}
}
var_dump($report);

PHP array of paths as HTML hierarchy

I have the following list of paths
GRUPA131/LFA & others/lfa sub.zip
GRUPA131/LFA & others/lfandrei.pdf
GRUPA131/Limbaje formale (Liviu Dinu).pdf
GRUPA131/desktop.ini
GRUPA131/lfa/lab1/1-Theodors MacBook Air.cc
GRUPA131/lfa/lab1/1.cc
GRUPA131/lfa/lab1/1.cc-Theodors MacBook Air.out
GRUPA131/lfa/lab1/1.cc.out
GRUPA131/lfa/lab1/2.cc
GRUPA131/lfa/lab1/input3.in
GRUPA131/lfa/lab1/tema1.zip
alexandru-lamba.png
alexandru-lamba_v2.png
analiza carte 1.pdf
analiza carte 2.pdf
biblsit.docx
center.js
as strings and I want to convert them into a folder hierarchy representable with HMTL. So, for each folder, I want to list it's files, and subfolders, and so on until the list is finished.
It would be best to have the php array hierarchy as follows:
$dirs['dirname'] -> file 1
$dirs['dirname'] -> file 2
$dirs['dirname'] -> file 3
$dirs['dirname'] -> Folder
$dirs['dirname']['folder'] -> file 1
$dirs['dirname']['folder'] -> file 2..
I have tried to split each string by '/' ( PATH_DELIMITER ) but I cannot figure out how to actually get an array like I have mentioned earlier.
Also, my array that has the entire paths, is a simple array. Not associative or so.
Can someone help me figure out how to do this?
Thanks!
Easiest way will be recursive function. My proposal:
function build_folder_structure(&$dirs, $path_array) {
if (count($path_array) > 1) {
if (!isset($dirs[$path_array[0]])) {
$dirs[$path_array[0]] = array();
}
build_folder_structure($dirs[$path_array[0]], array_splice($path_array, 1));
} else {
$dirs[] = $path_array[0];
}
}
$strings = array(
'GRUPA131/LFA & others/lfa sub.zip',
'GRUPA131/LFA & others/lfandrei.pdf',
'GRUPA131/Limbaje formale (Liviu Dinu).pdf',
'GRUPA131/desktop.ini',
'GRUPA131/lfa/lab1/1-Theodors MacBook Air.cc',
'GRUPA131/lfa/lab1/1.cc',
'GRUPA131/lfa/lab1/1.cc-Theodors MacBook Air.out',
'GRUPA131/lfa/lab1/1.cc.out',
'GRUPA131/lfa/lab1/2.cc',
'GRUPA131/lfa/lab1/input3.in',
'GRUPA131/lfa/lab1/tema1.zip',
'alexandru-lamba.png',
'alexandru-lamba_v2.png',
'analiza carte 1.pdf',
'analiza carte 2.pdf',
'biblsit.docx',
'center.js'
);
$dirs = array();
foreach ($strings As $string) {
$path_array = explode('/',$string);
build_folder_structure($dirs,$path_array);
}
print_r($dirs);
Check:
What is a RECURSIVE Function in PHP?
http://php.net/manual/en/language.references.pass.php

Required output generated for json data

{"99.net":{"status":"regthroughothers","classkey":"dotnet"},
"99.org": {"status":"regthroughothers","classkey":"domorg"},
"99.mobi":{"status":"regthroughothers","classkey":"dotmobi"},
"99.name":{"status":"Invalid Domain Name","classkey":"dotname"},
"99.us":{"status":"regthroughothers","classkey":"domus"},
"99.com":{"status":"regthroughothers","classkey":"domcno"},
"99.info":{"status":"Invalid Domain Name","classkey":"dominfo"},
"99.co.uk":{"status":"available","classkey":"thirdleveldotuk"},
"99.biz":{"status":"Invalid Domain Name","classkey":"dombiz"},
"99.in":{"status":"Invalid Domain Name","classkey":"dotin"}}
I'm able to display the output with the following code:
$json1 = json_decode($response1);
foreach($json1 as $key=>$sel_rows)
{
echo $key ;
echo " status: ". $sel_rows->status." ";
echo " Class: ". $sel_rows->classkey." ";
echo "Price";
echo "<br>";
}<br>
Now, I need to sort it so that a table such as the following can be shown:
<table border="1">
<tr>
<td>.com</td>
<td>.net</td>
<td>.info</td>
<td>.org</td>
</tr>
<tr>
<td>ADD</td>
<td>ADD</td>
<td>ADD</td>
<td>ADD</td>
</tr>
</table>
I'm having trouble figuring out how to sort the response in a way that I can use to generate this table, using the response data to add tool tips to the ADD links (like dinakar.com).
$json1 = json_decode($response1, TRUE);
foreach($json1 as $key=>$sel_rows)
{
echo $key ;
echo " status: ". $sel_rows['status']." ";
echo " Class: ". $sel_rows['classkey']." ";
echo "Price";
echo "<br>";
}
It looks like you're not having a problem decoding the response, but rather normalizing it for what you need to display. To do that, you'll need to extract the TLD from the domain string, unless you know it ahead of time. Presumably you do, as it was used to request the response to begin with?
Anyway, the following code illustrates one way of getting it into an array suitable for you to pass to your view (or however you're doing it):
$response1 = <<< EOF
{"99.net":{"status":"regthroughothers","classkey":"dotnet"},
"99.org": {"status":"regthroughothers","classkey":"domorg"},
"99.mobi":{"status":"regthroughothers","classkey":"dotmobi"},
"99.name":{"status":"Invalid Domain Name","classkey":"dotname"},
"99.us":{"status":"regthroughothers","classkey":"domus"},
"99.com":{"status":"regthroughothers","classkey":"domcno"},
"99.info":{"status":"Invalid Domain Name","classkey":"dominfo"},
"99.co.uk":{"status":"available","classkey":"thirdleveldotuk"},
"99.biz":{"status":"Invalid Domain Name","classkey":"dombiz"},
"99.in":{"status":"Invalid Domain Name","classkey":"dotin"}}
EOF;
function get_tld($url) {
$host = parse_url($url);
$domain = $host['path'];
$tail = substr($domain, -7); // Watch out, gotcha! Be sure of this.
$tld = strstr($tail, ".");
return $tld;
}
$domains = array();
$json1 = json_decode($response1);
foreach ($json1 as $idx => $obj) {
$tld = get_tld($idx);
$domains[$tld] = array('tld' => $tld, 'status' => $obj->status, 'classkey' => $obj->classkey);
}
This is off the top of my head. The resulting $domains array looks like this (truncated for brevity):
Array
(
[.net] => Array
(
[tld] => .net
[status] => regthroughothers
[classkey] => dotnet
)
[.org] => Array
(
[tld] => .org
[status] => regthroughothers
[classkey] => domorg
)
Note, I'm not doing a whole lot of sanity here, but that should be enough to help you sink your teeth into it. You'd then just make your table head off the keys, and populate your add links with whatever information they need that was returned in the response.

Categories