problem with php: read filenames, generate javascript and html - UPDATE [duplicate] - php

UPDATE
Hello again. I found myself with a new problem. The php code worked perfectly on my PC (wamp server) but i've now uploaded it on a free webhost server and while the php part runs perfectly (it produces the array) the javascript function itself doesn't work cause there are no photos in the website when it's loaded. I tried to test it by putting in the function's first line an alert to see if it runs but never showed up. I think that the server for some reason doesn't realise that it is a javascript function because i also had in the getphotos.php this:
window.onload = photos();
which appart from starting the photos function, shows a text. When i moved that line in js file and put the show text line first, it run showing the text but still no photos. What do you think????
END OF UPDATE
Hello to everyone. I am building a website that shows some photos. I want the site to automatically generate the html code that shows the photos by reading the file names in the photo folder, but i need also to use javascript. So I found through the web a solution with php generating javascript which than generates the html code I want and I think this is what I need. But... it doesn't work X_X. So I need someone's help!
Firstly, here is the php/javascript(in getPhotos.php):
<?
header("content-type: text/javascript");
//This function gets the file names of all images in the current directory
//and ouputs them as a JavaScript array
function returnImages() {
$pattern="(*.jpg)|(*.png)|(*.jpeg)|(*.gif)"; //valid image extensions
$files = array();
$curimage=0;
if($handle = opendir('/photos/')) {
while(false !== ($file = readdir($handle))){
if(eregi($pattern, $file)){ //if this file is a valid image
//Output it as a JavaScript array element
echo 'galleryArray['.$curimage.']="'.$file .'";';
$curimage++;
}
}
closedir($handle);
}
return($files);
}
//here starts the javascript function
echo 'window.onload = photos;
function photos(){
var i;
var text1 = "";
var text2 = "";
var text3 = "";
var galleryArray=new Array();'; //Define array in JavaScript
returnImages(); //Output the array elements containing the image file names
//short the images in three sets depending on their names and produce the code
echo 'for(i=0; i<galleryArray.length; i++){
if(galleryArray[i].indexOf("set1_")!=-1){
text1+= "<a rel=\"gallery\" title=\"\" href=\"photos/"+galleryArray[i]+"\">\n<img alt=\"\" src=\"photos/"+galleryArray[i]+"\" />\n</a>\n" ;
}else if(galleryArray[i].indexOf("set2_")!=-1){
text2+= "<a rel=\"gallery\" title=\"\" href=\"photos/"+galleryArray[i]+"\">\n<img alt=\"\" src=\"photos/"+galleryArray[i]+"\" />\n</a>\n" ;
}else if(galleryArray[i].indexOf("set3_")!=-1){
text3+= "<a rel=\"gallery\" title=\"\" href=\"photos/"+galleryArray[i]+"\">\n<img alt=\"\" src=\"photos/"+galleryArray[i]+"\" />\n</a>\n" ;
}
}';
//create text nodes and put them in the correct div
echo 'var code1 = document.createTextNode(text1);
var code2 = document.createTextNode(text2);
var code3 = document.createTextNode(text3);
document.getElementById("galleryBox1").appendChild(code1);
document.getElementById("galleryBox2").appendChild(code2);
document.getElementById("galleryBox3").appendChild(code3);
}';
?>
And this is the code in the mane page index.html:
<script type="text/javascript" src="getPhotos.php"></script><!--get photos from dir-->
This is it, and it doesn't work! I know I ask to much by just giving all the code and asking for help but i can't even think what's wrong, let alone how to fix it.... So please, if you have any idea it would be great.

; after returnImages() is missing.
This function (readdir) may return Boolean
FALSE, but may also return a
non-Boolean value which evaluates to
FALSE, such as 0 or "". Please read
the section on Booleans for more
information. Use the === operator for
testing the return value of this
function.
http://php.net/manual/en/function.readdir.php
So try to use while(false != ($file = readdir($handle))){
or while(FALSE !== ($file = readdir($handle))){

Your regular expression is wrong, for one. You need to look at a regex tutorial, like this one.

Related

PHP check if file_exists without extension then Ajax a div with appropriate media tag (img or video) based on filepath

First posting here. I know inline php is not preferred but I haven't converted all my scripts to echo json_encoded arrays to work in javascript on the client side...so for now, I have inline php.
I do not know the extension of the user uploaded media because it could be a jpg,mp4,etc and upon upload it goes into a media folder with the user id as an identifier.
When my user first loads the div (and html page), the php script cycles through an array and does a fetch_assoc from sql query to the database each time; It returns the (media_id #) and prints out an li with the respective media displayed next to some other values from the query.
I only know the (media_id) and the file path name without the extension. When the page first loads, everything works great and the file_exists function returns correctly.
THE PROBLEM
When I AJAX the div and do the query again, because the user added a row to the database, the new list prints out with all info, BUT the file_exists function doesn't recognize the exact same paths as before and I don't have an img or video on the page.
I copy/pasted the exact same code from the original div and put it in a file for ajax to re-query and print the new li's.
All variables are the same and when I hard code a test filepath, it prints fine. Maybe there's a caching issue?
THE CODE
<?php
$result=$conn->query($select);
$row=$result->fetch_assoc();
?>
<li>
<?php
if ($row['count']>0) {
echo "<div class='media-container'>";
$pathname = "uploads/".$row["id"]."media1";
$testjpg=$pathname.".jpg";
$testjpeg=$pathname.".jpeg";
$testpng=$pathname.".png";
$testmp4=$pathname.".mp4";
if (file_exists($testjpg)==TRUE || file_exists($testpng)==TRUE || file_exists($testjpeg)==TRUE) {
echo '<img src="'.$pathname.'">';
}if(file_exists($testmp4)==TRUE) {
echo "<video></video>";
}
echo "</div>";
}?>
</li>
I could use some advice on how to fix this and how to print appropriate media tags on unknown media types.
THE OUTPUT
<div class='media-container'>
</div>
DEBUGGING ATTEMPTS
echoing the exact file path of a known image in an <img> tag works fine. putting echo'test'; inside the file_exists case does nothing.
--
Solution (Kind of)
So I've used html's onerror before and I found a workaround, though I'd still like to know why I was getting an error. PSA this uses JQuery but javascript works too:
My Solution
<script>
function img2video(el, src) {
$( el ).replaceWith( '<video class="videoClass"><source src="'+src+'" type="video/mp4"></video>' );
}
</script>
<body>
<img style="width:100%" onerror="img2video(this,'<?php echo$pathname;?>')" src="<?php echo$pathname;?>">
</body>
Alright, so here's the final answer I made to best fit the problem using glob:
Javascript:
function img2video(el,src,place) {
if (place=='type') {
$( el ).replaceWith( '<video controls controlsList="nodownload" disablePictureInPicture style="width:100%;object-fit:contain;" preload="auto"><source src="'+src+'" type="video/mp4"></video>');
}
}
PHP:
<?php for ( $i=1; $i <= $limit; $i++) {
$path ="[DIRECTORY]/".$row["id"]."media".$i;
$path = (!empty(glob($path . '*.{jpg,png,jpeg,avi,mp4}', GLOB_BRACE)[0])) ? glob($path . '*.{jpg,png,jpeg,avi,mp4}', GLOB_BRACE)[0] : false;?>
<div>
<img onerror="img2video(this,'<?php echo$path;?>','type',<?php echo$row["id"];?>,<?php echo$i;?>)" src="<?php echo$path;?>">
</div>
<?php } ?>
I don't know how to mark as duplicate, if someone could help with that. My answer uses Glob_Brace from #Akif Hussain 's response on This Question.

PHP Function "opendir()" in Wordpress. Works in one file, but not in other

Alright, this will need a long explanation. Sorry if it's too long:
/////////////// INTRODUCTION ///////////////
There doesn't seem to be much information around about using opendir() within Wordpress and the way it should be implemented. However, after a couple hours of research, trial and error, I got it working on a custom page template.
I need it to fetch game thumbnail images from folders and output them as a grid, divided by categories (each folder is a category).
/////////////// MY APPROACH ///////////////
I created a function in functions.php that opens and reads a folder using the following relative path:
"wp-content/games/".$category."/"
Where $category is the argument of the function (defined by the user).
This is how my function looks like now:
function fetch_game_images($category){
//$category = 'featured';
$imageFiles = array();
$extensions = array('.JPG','.PNG');
$directory = "wp-content/games/".$category."/";
$openDir = opendir($directory);
while ($imgFile = readdir($openDir))
{
if ($imgFile <> '.' and $imgFile <> '..')
{
$extension = strtoupper(substr($imgFile, strrpos($imgFile, '.')));
if (in_array($extension, $extensions))
{
$imageFiles[] = $imgFile;
}
}
}
closedir($openDir);
foreach ($imageFiles as $k => $v)
{
$withoutExt = preg_replace("/\\.[^.\\s]{3,4}$/", "", $v);
$hyphenlessName = str_replace("-"," ",$withoutExt);
$formattedName = strlen($hyphenlessName) > 24 ? substr($hyphenlessName,0,24)."..." : $hyphenlessName;
if ($category == 'featured'){
if (strpos($formattedName,'netent') !== false) {$finalName = trim($formattedName, 'netent');}
else if (strpos($formattedName,'mg') !== false) {$finalName = trim($formattedName, 'mg');}
else { $finalName = $formattedName;}
}
else { $finalName = $formattedName;}
echo '<div class="games-list-item"><div class="game-container">';
echo '<a href=""><img src="'.get_bloginfo('url').'/'.$directory.'/'.$v.'" alt=""/>';
echo '<h3>'.$finalName.'</h3></a>';
echo '<div class="game-hover">';
echo '<img src="'.get_bloginfo('url').'/'.$directory.'/'.$v.'" alt=""/>';
echo '<div class="game-buttons-holder"><a class="play_now_btns" href="">Play Now</a><a class="free_play_btns" href="">Free Play</a></div></div><!--.game-hover-->';
echo '</div><!--.game-container--></div><!--.games-list-item-->';
}
}
/////////////// MY APPROACH RESULTS ///////////////
When I load the Wordpress Page using the Page Template that calls this function, it loads the images flawlessly.
But then, I have to change the games category dynamically using jQuery, I take the category/folder name, save it in a JavaScript variable and send it to a php that grabs it and passes it to the fetch_game_images(); function.
My jQuery GET looks like this:
$('#sidebar-list-menu li a').live('click', function(){
event.preventDefault();
var category = $(this).data('category');
//alert(cat);
//$('div.games-grid').html('<span class="loadingNotification">LOADING</span>');
$.get("<?php bloginfo('template_directory'); ?>/games-list-loader.php?category="+category,
function(data){
//alert(data);
//$('span.loadingNotification').remove();
$('div.games-grid').html(data);
});
});
And the PHP File (located in the same theme directory) looks like this:
<?php $parse_uri = explode( 'wp-content', $_SERVER['SCRIPT_FILENAME'] );
require_once( $parse_uri[0] . 'wp-load.php' );
$cat = $_REQUEST['category'];
fetch_game_images($cat);
?>
<div class="clear"></div>
/////////////// THE ISSUE ///////////////
The issue is that when I click on the sidebar link that triggers the GET call and tries to fetch the data from the PHP, it outputs the following error:
Warning: opendir(wp-content/games/featured/) [function.opendir]: failed to open dir: No such file or directory in [...]
Which shouldn't happen at all, since both my Page Template and my custom PHP file are in the same directory and load Wordpress core to use functions.php.
/////////////// THE QUESTION ///////////////
Does anybody know what could be the reason behind this behaviour? I read most of the google results I could find about this opendir() error, but most of them seem to point at a wrong path, but mine seem to be correct.
Others say that it might be a permissions issue. But I got my folders set to 755 and the files to 644.
So, any help would be great!
Thank you.
<======== /////////// EDIT ///////// =========>
Thanks to the help by #CBroe, I figured it out:
Instead of using a loose path like
"wp-content/games/".$category."/"
I changed it to a server-relative one
ABSPATH . "/wp-content/games/".$category."/"
And then I just changed the output to match the changes:
echo '<img src="'.get_bloginfo('url').'/wp-content/games/'.$category.'/'.$v.'" alt=""/>';
This works from both locations and solved the GET issue.
Most likely your relative path is not the correct one – usually happens when scripts are run from two different physical locations.
Making a debug output of getcwd() directly before calling opendir will show you what directory the scripts are actually running in in both cases – and that location is the one used to “complete” the relative path, so if those don’t match it’s only natural one of them will fail.
Relative paths are always tricky that way. It’s usually preferable to use a path relative to the server root (starting with a /) to avoid such issues.

Styling each result of an fgets($file) list differently, is it possible?

G'day, first post so here we go. Very open to suggestions as I'm not sure if it's possible to do what I want with the type of coding I am using. Kinda new/rusty to coding, been a LOOOONG time.
Purpose of current coding:
I have a .txt file with a list of file names (map names to be exact for my situation, each on it's own line) that is constantly being changed and modified as we add/remove maps. I am using a script on a .php page to parse the contents of that file and display the results on a webpage. The script outputs each map name to a variable that is wrapped in an href tag, which results in a link to download that particular map. This continues until all maps have been created in a list, each as a link to download that map.
Problem I am having:
I do not wish some maps/entries to be created as links, and only as text. Is there a way to filter the results of an fgets() and style them different based on value? So like map1-map4 all get turned into download links but map5 does not, then map6 and on continue to be download links.
Current script/code being used:
<?php
$file = fopen("maplists/dodgeball.ini", "r");
while (!feof($file)) {
$dbmapname[] = fgets($file);
}
fclose($file);
foreach ($dbmapname as $dbmap){
echo "<a href='http://www.mydownloadurl.com/fastdl/maps/" . $dbmap . ".bsp.bz2'>$dbmap</a><br />";
}
?>
Coding revised thanks to help below. Here is my current coding to produce what I was looking for:
foreach ($dbmapname as $dbmap){
if(!in_array($dbmap, $stockmaps)){
echo "<a href='http://www.mydownloadurl.com/fastdl/maps/" . $dbmap . ".bsp.bz2'>$dbmap</a><br />";
}
else echo $dbmap."<br />";
}
I am still having a slight issue though regarding the last entry of the array being forced to be a link regardless if it is in the $stockmaps array or not.
There are a ton of ways to implement this. Below I've presented a nice general way where you create an array of maps for which you don't want a link and then loop through and print either link or the plain text depending on whether each map is in the list.
<?php
$file = fopen("maplists/dodgeball.ini", "r");
while (!feof($file)) {
$dbmapname[] = trim(fgets($file));
}
fclose($file);
$nolink = array( $dbmapname[4] ); //fifth map
foreach ($dbmapname as $dbmap){
if(!in_array($dbmap, $nolink)){
echo "<a href='http://www.mydownloadurl.com/fastdl/maps/" . $dbmap . ".bsp.bz2'>$dbmap</a><br />";
}
else echo $dbmap."<br />";
}
}
?>
You can add item to the filter based on whatever criteria you want
//Add item 2 to the list
$nolink[] = $dbmapname[1];
//Add all items after item 20 to the list
$nolink = array_merge($nolink, array_slice($dbmapname, 20));
//Don't link a specific set of maps
$nolink = array('bad_map', 'another_map_not_to_show');

Updating HTML files using PHP from form input

Basically, I want to update static HTML files with code snippets input by users from a standard form. I understand how updating the files work, I'm just unsure as to how I go about including the code input from the form to my php file, which is shown below.
<?php
if($handle = opendir()) {
$search = '</body>';
replace = <<< EOF
<!-- I want to populate this with form field input.-->
EOF;
while(false !== ($entry = readdir($handle))) {
if(is_dir($entry)) continue;
$content = file_get_contents($entry);
$content = str_replace($search, $replace . '</body>', $content);
file_put_contents($entry, $content);
}
}
echo 'done';
?>
Any help greatly appreciated.
I would approach this a bit differently. I suggest having a template file aside from the one being modified. That way, you are always modifying a fresh copy instead of having to worry about what changed in the new version.
If your needs become more advanced beyond simply dropping in some markup, I might suggest using a DOM parser.
Finally, I'm sure you have a good reason for writing these static files... just remember the security implications of doing so. You're effectively letting someone do almost anything they want to your server.
Although I agreed it was in no way the best solution to the specific problem, for anyone that may find this useful in the future I used file_get and str_replace to achieve desired results. The code below will allow you to search a file for a specific term and replace with whatever you want based on form input.
<?php
//These are the variables the html file will post to the script.
$filename = $_POST['myFile'];;
$tofind = $_POST['myFind'];;
$toreplace = $_POST['myReplace'];;
$file = file_get_contents($filename);
$end = str_replace($tofind, $toreplace, $file);
$fp = fopen($filename, "w"); //Open the filename and set the mode to Write
if(fwrite($fp, $end)) ; //Write the New data to the opened file
fclose($fp); //Close the File
echo(" File name is $filename ... Finding $tofind .... Replacing with $toreplace ..... Done !");
?>
Though it's a horrible solution, mixed with your code this will do
$replace = array_key_exists('input',$_REQUEST) ? $_REQUEST['input'] : '';
//$replace = sanitize($replace); // there's so much bad with this string
//do the needfull
?>
<form method='GET' action='#'>
<input type='text' name='input' />
<input type='submit' />
</form>

Pull dedicated images from folder - show image + filename (strip part of filename + file-extension)

based on the original code in this question and Tims correction over there (answer 1) I'm trying to achieve the following:
I have a folder "img" containing images as follows:
image_123.jpg
image_123_alternate.jpg
image_456.jpg
image_456_alternate.jpg
image_789.jpg
image_789_alternate.jpg
and so on...
(Note: all images have the same size of 200px/200px)
When pulling from the "img" folder the simple HTML page should display images and filenames in the following fashion:
The actual images that contain the "_alternate" part in their filename (and only these) + the image filename not containing the "_alternate" part (without the file-extension) underneath the image in a textbox. All pairs should be pulled in an alphabetical order. In the example below bold capital letters indicate the actual image to be displayed:
IMAGE_123_ALTERNATE
textbox: "image_123"
IMAGE_456_ALTERNATE
textbox: "image_456"
IMAGE_789_ALTERNATE
textbox: "image_789"
This is what I have so far but this displays all images and filenames:
<?php
$dir = opendir("img");
while (($file = readdir($dir)) !== false)
{
echo "<a href='img/".$file."' target='_blank'> <img src='img/".$file."'width='200' height='200' /></a><br />";
echo "<textarea>$file</textarea><br /><br />";
}
closedir($dir);
?>
Any help would be much appreciated!
Thanks a lot!
This code should display a list of all images in alphabetical order (using PHP's GLOB function).
It then outputs a HTML image (leading to the "_alternate" image) and the image's filename (without the path, "_alternate" or "extension").
<?php
foreach (glob("img/*_alternate.jpg") as $file) {
$filename_parts = pathinfo($file);
$filename = $filename_parts['filename'];
$filename = str_replace("_alternate", "", $filename);
echo "<div>";
echo "<img src=\"/$file\" width=\"200\" height=\"200\" />";
echo "<p>$filename</p>";
}
?>
I have broken apart the functions that find the new filename and the parts that output the HTML code to make it easier to read and understand, you could merge these into one function if you wanted to.
Just through an if statement in your while loop. Check if the file name contains alternate or or not. If it doesn't contain alternate run your same code replacing the file extension with "_alternate.ext" while keeping the text area the same. If it does contain alternalte, do nothing. That way you are only processing half the files.
$files = new \DirectoryIterator('img'); // <- this should be the full absolute path!
$images = array();
// pick up jpg images that end in 'alternate'
foreach($files as $file){
$name = $file->getBasename('.jpg');
if(strripos($name, 'alternate') === (strlen($name) - 9))
$images[] = $name;
}
// sort them
sort($images, SORT_STRING);
// and do your thing here with $images...
var_dump($images);

Categories