PHP, need file to be overwritten or deleted after use - php

I have written a function to get a file from S3 and get the number of pages from it. (It's a PDF.) Everything works fine until I try and do the same for multiple files. Now it is just returning the number of pages of the last file. I think that the problem is that local.pdf needs to be deleted or overwritten, but I'm not sure how. I thought it would automatically overwrite it.
I tried using $pdf->cleanUp(); but that doesn't seem to do anything. It is still returning the page count of the last file.
This is the function that gets called for each child job:
public function getPageCountPDF($jobid) {
$this->load->library('Awss3', null, 'S3');
$PdfTranscriptInfo = $this->MJob->getDOCCSPdfTranscript($jobid);
$filename = $PdfTranscriptInfo['origfilename'];
$PdfFilename = 'uploads/' . $jobid . '/' . $filename;
$localfilename = FCPATH . 'tmp\local.pdf';
$this->S3->readfile($PdfFilename, false, 'bucket');
require_once 'application/libraries/fpdi/fpdf.php';
require_once 'application/libraries/fpdi/fpdi.php';
$pdf = new FPDI();
$pageCount = $pdf->setSourceFile($localfilename);
$pdf->cleanUp();
return $pageCount;
}
I am not getting any error messages, but the $pageCount should be 8 and then 6. The return I am getting from the function is 6 and 6.
I also tried adding
ob_clean();
flush();
But that clears the whole page, which I don't want.
I also tried using a generated name instead of local.pdf, but that doesn't work (I get a "cannot open file" message).
EDIT: This is the part that calls the function getPageCountPDF($jobid):
foreach ($copies as $copy) {
.
.
$CI = &get_instance();
$pageCount = $CI->getPageCountPDF($copy['jobid']);
.
.
}

What happens to $pageCount after
$pageCount = $CI->getPageCountPDF($copy['jobid']); ?
This gets overwritten after each iteration. Maybe you want something like $pageCount[$copy['jobid']] = $CI->getPageCountPDF($copy['jobid']); so you actually keep an array of $pageCounts to be processed further down the line.

function get_all_directory_files($directory_path) {
$scanned_directory = array_diff(scandir($directory_path), array(
'..',
'.'
));
return custom_shuffle($scanned_directory);
}
function custom_shuffle($my_array = array()) {
$copy = array();
while (count($my_array)) {
// takes a rand array elements by its key
$element = array_rand($my_array);
// assign the array and its value to an another array
$copy [$element] = $my_array [$element];
// delete the element from source array
unset($my_array [$element]);
}
return $copy;
}
So you can call get_all_directory_files which calls custom_shuffle
Then you can loop through while reading them. In case you want to delete the files
You can proceed with :
$arrayfiles = get_all_directory_files('mypath');
foreach ($arrayfiles as $filename) {
echo 'mypath/'.$filename; //You can do as you please with each file here
// unlink($filename); if you want to delete
}

Related

Searching for a specific string from all PHP files in the parent directory (Updated)

A while ago I made a post (Searching for a specific string from all PHP files in the parent directory) that was about me finding the position of the file path in an array, only if the file had a specific keyword.
However, that was in my old website, which I have now lost. So I am currently recreating it. However, for some reason this function does not work.
public function build_active_theme() {
$dir = CONPATH . '/themes/' . $this->get_active_theme() . '/';
$theme_files = array();
foreach(glob($dir . '*.php') as $file) {
$theme_files[] = $file;
}
$count = null;
foreach($theme_files as $file) {
$file_contents = file_get_contents($file);
if(strpos($file_contents, 'Main')) {
$array_pos = $count;
$main_file = $theme_files[$array_pos];
echo $main_file;
}
$count++;
}
}
This function causes the following error:
Notice: Undefined index: in /home/u841326920/public_html/includes/class.themes.php on line 30
I have narrowed the problem down the something wrong with the $count variable. Whenever I try and echo the $count value once the script has found the correct file, nothing is shown.
But after spending nearly an hour on such a simple problem, it is obviously starting to frustrate me, so I am now seeking help.
(Note: I directly copied the function directly from the old post into my code, and made the appropriate changes to variables to 'work' in the new site, so it's is pretty much exactly the same as the solution that fixed my previous problem - which funnily enough was also caused by the $count variable).
Thanks,
Kieron
You can use the foreach $key instead of a separate count variable, try the code below:
foreach($theme_files as $key => $file) {
$file_contents = file_get_contents($file);
if(strpos($file_contents, 'Main') !== false) {
$main_file = $theme_files[$key];
echo $main_file;
}
}
You are setting
$count = null;
, try to ++ it before the
$array_pos = $count;

Searching for a specific string from all PHP files in the parent directory

I am trying to figure out a way of searching through all of the *.php files inside the parent directory, parent directory example:
/content/themes/default/
I am not wanting to search through all of the files in the sub-directories. I am wanting to search for a string embedded in the PHP comment syntax, such as:
/* Name: default */
If the variable is found, then get the file name and/or path. I have tried googling this, and thinking of custom ways to do it, this is what I have attempted so far:
public function build_active_theme() {
$dir = CONTENT_DIR . 'themes/' . $this->get_active_theme() . '/';
$theme_files = array();
foreach(glob($dir . '*.php') as $file) {
$theme_files[] = $file;
}
$count = null;
foreach($theme_files as $file) {
$file_contents = file_get_contents($file);
$count++;
if(strpos($file_contents, 'Main')) {
$array_pos = $count;
$main_file = $theme_files[$array_pos];
echo $main_file;
}
}
}
So as you can see I added all the found files into an array, then got the content of each file, and search through it looking for the variable 'Main', if the variable was found, get the current auto-incremented number, and get the path from the array, however it was always telling me the wrong file, which had nothing close to 'Main'.
I believe CMS's such as Wordpress use a similar feature for plugin development, where it searches through all the files for the correct plugin details (which is what I want to make, but for themes).
Thanks,
Kieron
Like David said in his comment arrays are zero indexed in php. $count is being incremented ($count++) before being used as the index for $theme_files. Move $count++ to the end of the loop, And it will be incremented after the index look up.
public function build_active_theme() {
$dir = CONTENT_DIR . 'themes/' . $this->get_active_theme() . '/';
$theme_files = array();
foreach(glob($dir . '*.php') as $file) {
$theme_files[] = $file;
}
$count = null;
foreach($theme_files as $file) {
$file_contents = file_get_contents($file);
if(strpos($file_contents, 'Main')) {
$array_pos = $count;
$main_file = $theme_files[$array_pos];
echo $main_file;
}
$count++;
}
}

Php method not being called

I have been trying to debug this code for a while now, and it looks like the build method is not being called. I put echo's, var_dumps, and all other kinds of signs in it, but never get anything.
Full php code
class Auto_slideshow {
private $_img_dir;
//constructor sets directory containing the images
function __construct($dir) {
//Directory source from webroot
$_img_dir = $dir;
}
//Iterates through directory and constructs HTML img list
public function build() {
//use SPL for directory iteration
$iterator = new DirectoryIterator($_img_dir);
$html = '';
$i = 1;
//Iterate through directory
foreach ($iterator as $file) {
//set a variable to add class of "show" on first element
$showClass = $i === 1 ? ' class="show"' : null;
//exclude '.' and '..' files
if(!$iterator->isDot()) {
//set src attribute for img tag
$src = $_img_dir . $iterator->getFilename();
//Grab sizes of images
$size = getimagesize($_img_dir . $iterator->getFilename());
var_dump($src);
//create img tags
$html .= '<img src="' . $src . '" ' . $size[3] . $displayNone . ' />' . "\r\n";
$i++;
}
}
return $html;
}
}
html call
<center>
<div class="imagecontainer" id="auto-slideshow">
<?php
$show = new Auto_slideshow("../CMSC/images/master/slidestock/");
$show->build();
?>
</div>
</center>
I also tried print $show->build();, as the tutorial showed, which also did not work.
Update
I changed $_img_dir to $this->$_img_dir' and called the method byecho show->build();` and the method still isn't being called.
This is a matter of the method not even running, not even to the point of find the images yet.
Update 2
If I remove the entire php code within the html, the rest of the page loads just fine. As it is now, the html loads only to the div that contains the php then stop everything after it.
Have you used a var_dump() outside of the loop as well?
The problem is that your variable will remain NULL:
//constructor sets directory containing the images
function __construct($dir) {
//Directory source from webroot
// This is a local variable that will be gone when the constructor finishes:
$_img_dir = $dir;
}
You need:
//constructor sets directory containing the images
function __construct($dir) {
//Directory source from webroot
$this->_img_dir = $dir;
^^^^^^ here
}
You return the text you want to display but you don't display it:
echo $show->build();
Fix and update the code bellow:
Constructor:
$this->_img_dir = $dir;
build Function:
$iterator = new DirectoryIterator($this->_img_dir);
$src = $this->_img_dir . $iterator->getFilename();
$size = getimagesize($this->_img_dir . $iterator->getFilename());
You can call it:
echo $show->build();

Random file from folder (no repetition)

So I'm using the following code to pull a random file from a folder and I would like to make it so there is never a chance of pulling up the current file again (ie: seeing the same image/document twice in a row).
How would I go about this? Thanks in advance!
function random_file($dir = 'destinations')
{
$files = glob($dir . '/*.*');
$file = array_rand($files);
return $files[$file];
}
Store the last viewed filename in a cookie or in the session.
Here's how to do it with a cookie:
function random_file($dir = 'destinations') {
$files = glob($dir . '/*.*');
if (!$files) return false;
$files = array_diff($files, array(#$_COOKIE['last_file']));
$file = array_rand($files);
setcookie('last_file', $files[$file]);
return $files[$file];
}
$picker = new FilePicker();
$picker->randomFile();
$picker->randomFile(); // never the same as the previous
--
class FilePicker
{
private $lastFile;
public function randomFile($dir = 'destinations')
{
$files = glob($dir . '/*.*');
do {
$file = array_rand($files);
} while ($this->lastFile == $file);
$this->lastFile = $file;
return $files[$file];
}
}
Essentially: store the name of every file used in an array; every time you pull a new name, check whether it already exists in the array.
in_array() will help you with that. array_push() will help fill the "used files" array.
You could make the array a static one to have the list available whenever you call the function (instead of using global variables).
If you want to present a fixed set of files in random order,
then read all file names into an array, shuffle the array
and then just use the array from start to end.

PHP - Displaying random output more than once, prevent duplicate

I have the following code that I am using to randomly display PHP widgets from a folder:
<?php
function random_widget($dir = 'wp-content/themes/zonza/elements')
{
$files = glob($dir . '/*.*');
$file = array_rand($files);
return $files[$file];
}
?>
<?php include random_widget();?>
<?php include random_widget();?>
<?php include random_widget();?>
random_widget(); outputs a URL, which I then use in the include function to display the widget.
The code randomly chooses between 6 php files and displays one randomly. I include it 3 times to get 3 widgets. However, I get the same widget displayed more than once sometimes.
What can I do to modify the code to prevent this from happening?
Try this:
<?php
function random_widget($dir = 'wp-content/themes/zonza/elements')
{
static $files = false;
if(!$files) $files=glob($dir . '/*.*');
$key = array_rand($files);
$file=$files[$key];
unset($files[$key]);
return $file;
}
?>
It works by removing the file returned from $files, and maintaining $files over multiple function calls (it only globs() on the first time you call the function)
Declare files at the beginning of the page $files = glob($dir . '/*.*');
In random_widget, do this unset($files[$file]) after you pull the value.
array_rand takes a number $num_req as an optional second parameter which specifies the number of entries you want to pick. So add this parameter to random_widget, pass it to array_rand to get an array of keys instead of a single key, return the array of files, and then iterate over this array to include the widgets (instead of calling random_widget three times).
<?php
function random_widget($num_req, $dir = 'wp-content/themes/zonza/elements')
{
$files = glob($dir . '/*.*');
$keys = array_rand($files, $num_req);
$chosen = array();
foreach($keys as $key) {
$chosen[] = $files[$key];
}
return $chosen;
}
$widgets = random_widget(3);
foreach($widgets as $widget) {
include $widget;
}
?>
An advantage of this solution over the ones proposed in the other answers is that it is stateless: you can reuse the function in different contexts as much as you want.
Source: http://php.net/manual/en/function.array-rand.php

Categories