I have database columns attach1 and attach2.
I need to show files (pdf) from those columns, but only if they exist in directory www.domain.com/uploads.
Attach1 contains real file but attach2 does not.
I tried something like this:
<?php
$file = $row['attach'];
$exists = file_exists('uploads/'.$file.'');
if ($exists) {
echo $file;
}
if (!$exists) {
echo 'No file1';
}
?>
<?php
$file2 = $row['attach2'];
$exists = file_exists('uploads/'.$file2.'');
if ($exists) {
echo $file2;
}
if (!$exists) {
echo 'No file2';
}
?>
But everytime it echoes me back, that file exists, even when attach2 contains nothing. Why?
If your filename is empty, then you are passing only the directory name to file_exists. Directories are files too. And I reckon the directory does actually exist. It is not lying to you.
You can either check that the filename from the database is not empty, or you can pass the whole string to the function is_dir to see if it is a directory. I assume you only want regular files.
That would look something like this:
<?php
$file = $row['attach'];
$exists = file_exists('uploads/'.$file.'') && !is_dir('uploads/'.$file.'');
if ($exists) {
echo $file;
} else {
echo 'No file1';
}
?>
I changed the if statement to use an else clause. It is equivalent to using a second if like you did.
Related
when user select the file then in server side file extension will be removed or rename and uploaded it to the server using php codeigniter library
This should remove your file extension
<?php
$var = "testfile.php";
$explode = explode( '.', $var );
array_pop( $explode);
$var = implode( '.', $explode );
var_dump( $var );
As for uploading you will need to read the manual on file uploading
http://www.codeigniter.com/user_guide/libraries/file_uploading.html
file name can be changed using the following codes:
$your_given_name = time().rand().$_FILES["userfiles"]['name'];
$config['file_name'] = $your_given_name;
for changing extension you can use:
if ($this->upload->do_upload('file_name')) {
$file_data=$this->upload->data();
$new_name_by_you='anything'.$file_data['file_ext'];
$new_path=$file_data['file_path'].$new_name_by_you;
rename($file_data['full_path'], $new_path);
}
rename() is a php built in function. for details please visit http://php.net/manual/en/function.rename.php
I recently just had the same issue, and found it really annoying that even when you specified a file_name in code igniter it would append the file extension. Which i did not want.
Blinkydamo's link is not helpfull, since that is the link i was following in the first place and makes no mention of this dilema, although it does demontrate that it is not possible idrectly through Code Igniter - by ommission of the answer.
I haven't tried md asif rahman's method, but it looks sound.
Alternatively you can just forget about using Code Igniter's upload function, and fall back onto PHPs standard one, which is what I have done :
move_uploaded_file($_FILES['imageFile']['tmp_name'], '/path/'.$filename);
where $filename is the exact name of the file including extension, therefore if none is specified - it wont have one.
it is so easy
change code in
libraries/Upload.php
public function set_filename($path, $filename)
{
if ($this->encrypt_name === TRUE)
{
$filename = md5(uniqid(mt_rand()));
}
if ($this->overwrite === TRUE OR ! file_exists($path.$filename))
{
return $filename;
}
$filename = str_replace($this->file_ext, '', $filename);
$new_filename = '';
for ($i = 1; $i < $this->max_filename_increment; $i++)
{
if ( ! file_exists($path.$filename.$i))
{
$new_filename = $filename.$i;
break;
}
}
if ($new_filename === '')
{
$this->set_error('upload_bad_filename', 'debug');
return FALSE;
}
else
{
return $new_filename;
}
}
NagiosQL creates a file called servicetemplates.cfg.
For easier distribution of some selected templates I' d like to split any service definition into one seperate file.
Sample servicetemplates.cfg
define service {
name imap_service
use generic_service
check_command check_service_imap
register 0
}
define service {
name ldapserver_ldap_service
service_description LDAP
use generic_service
check_command check_service_ldap
icon_image ldapserver.png
register 0
}
What I like to have is some kind of parser, which create files like the "name" of the template, e. g. imap_service.cfg and ldapserver_ldap_service.cfg.
Every file have to include the whole definition (define service { ... } )
The following code is a solution for me, it might not be perfect as it expects a certain syntax of the Nagios object configuration.
The first parameter has to be the file name of the Nagios configuration file.
<?php
if (empty($argv[1])) {
echo "First parameter: File to Nagios object configuration\n";
exit(1);
}
$starttag=0;
$outfile='';
$outtext='';
$inputfile=$argv[1];
$cfgfile = file($inputfile) or exit(2);
foreach ($cfgfile as $line_num => $line) {
# $outtext will be reset if define ... { is found
$outtext.=$line;
# Start tag of a new section "define ... {"
if (preg_match("/.*define.*{/i", $line)) {
$starttag=1;
$outtext=$line;
}
# Split the line with name. The parameter after name is the later filename
if (preg_match("/name[\s]+[\w]+/", $line) && $starttag=1) {
$keywords=preg_split("/[\s]+/", $line);
$outfile=$keywords[2];
$outfile.=".cfg";
$outfile=str_replace(' ', '_', $outfile);
}
# End tag of a new section "}"
if (preg_match("/.*}/", $line) && $starttag=1) {
$starttag=0;
echo "Writing {$outfile}\n";
file_put_contents($outfile, $outtext);
}
}
echo "Read lines {$line_num} from {$inputfile}\n";
?>
I need help on writing a shell script to check if the owner and group matches the names I have in my IF statement. It needs to recursively check all files and folders, including the parent folder.
For example, my directory structure might look like this
/data
/data/folder1
/data/folder1/fileA
/data/folder2/fileB
I need to verify that data, folder1, folder2, fileA, fileB are all owned by the same owner and group.
#!/bin/bash
DIR="/data";
N=0;
for $DIR..
if [ NOT MATCH "username:groupname" ]; then
N=1;
fi
done
if [ $N -gt 0 ]; then
echo "all or some files and folders don't match";
else
echo "all files match";
fi
#!/bin/bash
OWNER=user
ACTUAL_OWNER='stat -c %U file'
N=0;
not_match(files)
{
if [ ! OWNER = ACTUAL_OWNER ]; then
N=1;
return;
else if [ not_end_of_file ]; then
not_match(files+1)
else
return
fi
}
DIR="/data";
not_match(files)
if [ $N -gt 0 ]; then
echo "all or some files and folders don't match";
else
echo "all files match";
fi
i wasnt sure of some of the exact commands or syntax so it has some sudo code but it is basically what you want to do. if they are a match and its not the end of the files you are searching call the function again and increase to the next file if it doesnt match say they dont and just return since you dont tell the user how many dont match and if the end is reached then success and return to print out to the user
Using Cake version 2.4.3 stable
So I am having a time here, I have modified this plug in to save files to the app folder https://github.com/srs81/CakePHP-AjaxMultiUpload/
The uploaded files are being saved to /public_html/app/files
Now the strange thing is, when trying to serve these files to the view, I can read the file name, the file size, but not the file itself, image, pdf, etc.
When I try to access the file via direct url, i get this error :
Error: FilesController could not be found.
How can it be that I can read the file name, the file size, but not the file itself?
There is a need to save the files in the app folder. These files should be protected and therefore only be accessed by users who are logged into the application. I have tried to use cake send file response with no outcome.
Edit : I guess the real question at hand here is how can I read files from APP . DS . 'files' ?
View code :
public function view ($model, $id, $edit=false) {
$results = $this->listing ($model, $id);
$directory = $results['directory'];
$baseUrl = $results['baseUrl'];
$files = $results['files'];
$str = "<dt>" . __("Pictures") . "</dt>\n<dd>";
$count = 0;
$webroot = Router::url("/") . "ajax_multi_upload";
foreach ($files as $file) {
$type = pathinfo($file, PATHINFO_EXTENSION);
$filesize = $this->format_bytes (filesize ($file));
$f = basename($file);
$url = $baseUrl . "/$f";
if ($edit) {
$baseEncFile = base64_encode ($file);
$delUrl = "$webroot/uploads/delete/$baseEncFile/";
$str .= "<a href='$delUrl'><img src='" . Router::url("/") .
"ajax_multi_upload/img/delete.png' alt='Delete' /></a> ";
}
$str .= "<img src='$url' /> ";
$str .= "<a href='$url'>" . $f . "</a> ($filesize)";
$str .= "<br />\n";
}
$str .= "</dd>\n";
return $str;
}
And the upload / save
public function upload($dir=null) {
// max file size in bytes
$size = Configure::read ('AMU.filesizeMB');
if (strlen($size) < 1) $size = 20;
$relPath = Configure::read ('AMU.directory');
if (strlen($relPath) < 1) $relPath = "files";
$sizeLimit = $size * 1024 * 1024;
$this->layout = "ajax";
Configure::write('debug', 0);
$directory = APP . DS . $relPath;
if ($dir === null) {
$this->set("result", "{\"error\":\"Upload controller was passed a null value.\"}");
return;
}
// Replace underscores delimiter with slash
$dir = str_replace ("___", "/", $dir);
$dir = $directory . DS . "$dir/";
if (!file_exists($dir)) {
mkdir($dir, 0777, true);
}
$uploader = new qqFileUploader($this->allowedExtensions,
$sizeLimit);
$result = $uploader->handleUpload($dir);
$this->set("result", htmlspecialchars(json_encode($result), ENT_NOQUOTES));
}
The only real change from the original plug in is changing WWWROOT to APP to make the switch. Saving works fine and lovely. But its just weird that I can read the file name, file size in the view no problem but cannot view an image, pdf, etc.
The problem:
You cannot display files that are outside the webroot via a direct URL - that's the whole point in putting them above the webroot in the first place - to make them NOT directly accessible.
So building the image src path in the controller first (not good practice anyway) won't change the fact that when that path gets to the browser, and it reads the source of the image as trying to pull an image from above webroot, it won't/can't.
The Solution:
The solution is to use a CakePHP's Sending files (what used to be Media Views). Then, you set your img's "src" to a controller/action. In that action, it basically says "display this action as an image" (or pdf, or whatever else).
Path to use in Controller:
took this from one of my apps which is doing exactly the above, and here's the path I used for a file in 'files' (same level as webroot):
file_exists(APP . 'files' . DS . $your_filename)
Create a symbolic link to your folder inside of the webroot ;-)
I wish to display the results of a database query in my view whilst giving each row a unique ID.
My model is:
function get_load_lines($ordernumber)
{
$this->db->select('product,pricepercube,qty,linecost,linediscount,cubicvolume,bundles,treated,autospread');
$this->db->from('Customer_Order_Lines');
$this->db->where('CustomerOrderID',$ordernumber);
$q = $this->db->get();
if($q->num_rows() > 0)
{
return $q->row_array();
}
}
My controller is:
function edit_order_lines()
{
$data = array(
'ordernumber' =>$this->input->post('ordernumber'),
'customer' =>$this->input->post('customer'),
'loadlines' => $this->sales_model->get_load_lines($this->input->post('ordernumber'))
);
$this->load->view('sales/edit_order_lines',$data);
}
As mentioned I want to display each of these rows in my view.
So I use this code in my view:
<table>
<?php
$i=1;
foreach ($loadlines as $row)
{
echo "<tr>";
echo "<td>".$i."</td>";
echo "<td>".$row['product']."</td>";
echo "<td>".$row['pricepercube']."</td>";
echo "<td>".$row['qty']."</td>";
echo "</tr>";
$i++;
}
?>
</table>
This does not have the intended result. $i increments for each array entry, not each array line.
Any advice on the best way to display this data?
So if 3 rows the below is required:
In your model, try returning a result_array, rather than a row_array:
return $q->result_array();
If more than one result exists, result array will return all of the results, whereas row array will only return one. CodeIgniter's user guide explains the differences.
You could also make your for loop at little bit tidier, by incrementing $i like this:
$i=1;
foreach ($loadlines as $row)
{
echo "<tr>";
echo "<td>".$i++."</td>";
echo "<td>".$row['product']."</td>";
echo "<td>".$row['pricepercube']."</td>";
echo "<td>".$row['qty']."</td>";
echo "</tr>";
}
I'm not sure I understand you question clearly, but in order to edit Customer Order Line (order details) you should also pull the ID of each Customer_Order_Lines when you query the database. (assuming your table Customer_Order_Lines has primary key filed called ID).
$this->db->select('id,product,pricepercube,q...');
Then when you loop through the results, do:
foreach ($loadlines as $row)
{
echo "<tr>";
echo "<td>".$row['id']."</td>";
echo "<td>".$row['product']."</td>";
echo "<td>".$row['pricepercube']."</td>";
echo "<td>".$row['qty']."</td>";
echo "</tr>";
$i++;
}
This will give you the specific unique ID's (primary keys) of each Order Line. Then, you can updated each Order Line by referring to this ID.
Let me know if I misunderstood your question.