How to write metadatas to a file? - php

I am currently developing a web solution in PHP 8.0 using Symfony 5.3.7 where I need to allow user to download a file with custom metadatas.
For example, I have on the server a file a.jpg and I created a metadata "Resume: John is looking to Marie", which is stored and linked to the file in database.
If a user click on a button to download the file, I need to set the metadata stored in database to the file before the user download it, then if he bring is a.jpg in USB key or whatever, the metadata is in it.
Does anyone knows how to do with Symfony or even native PHP?
I am thinking of create a download function to do this but I don't find how to write the metadata in the file.
The only thing I could find is this https://www.php.net/manual/fr/pharfileinfo.setmetadata.php, but I don't even understand how it works.
I need this for multiple file types : images, videos, audios and PDFs.

There is no universal way to add arbitrary metadata like this to a file, regardless of whether you're using PHP or anything else.
At its most basic, a file is just a series of bits, and the way we interpret those bits is what we call a "file format". Some file formats are very simple - the whole file is interpreted as a series of letters, or a series of coloured pixels; others are much more complex, with different sections interpreted as different types of information.
A JPEG image file, for instance, can have sections of data referred to as "EXIF information", which can store details about the image, including arbitrary text. Similarly, MP3 files can have sections called "ID3", which are used to store things like track and artist names to be displayed by media players. You can probably find tools or libraries for editing both of those formats, but you won't be able to use an EXIF editor on an MP3 file or an ID3 editor on a JPEG.
The function you found was for managing the metadata on PHAR files, which are PHP code archives. It's not going to be useful for editing images, PDFs, or anything else.
So, you need to identify the different types of file you want to edit, and then find out two things: firstly, does the file format have anywhere to put the metadata at all; and secondly, what tools can edit the metadata in that particular file type. You might find some libraries or tools which can manage metadata in multiple audio formats, or multiple image formats, but chances are you're going to need to integrate more than one to get the breadth of support you seem to want.

Related

Hide text inside audio file with PHP

Is it possible to add a hidden string to an audio file (MP3, mid) via PHP?
I have an online music store and some of my customers resell the songs, and I want to hide his e-mail address in the audio file to identify them.
Audio Files
For real audio files (not MIDI, which is not really an audio file), the best method for this is to use audio watermarking. There are many algorithms and tools (such as AWT) that can be executed from your PHP script to handle this. They work by modifying the audio data in a way that cannot be perceived but can be decoded.
Most of these algorithms can encode the watermark in such a way that they survive re-encoding with other codecs. This is a critical difference from what you are asking for. If you simply were to add an ID3 tag, any tool could remove that. In fact, it's likely your tag would get removed just by tools that read and re-write your ID3 tags. With the information embedded in the actual audio itself however, it will survive. If someone decodes the file and re-encodes with another codec, depending on your watermarking algorithm, the watermark will still survive. Even if someone streams it within another stream, the watermark can survive.
and I want to hide his e-mail address in the audio file to identify them
Rather than embedding personally identifying information, you should store an ID or hash of an ID that you keep in your own database. It might be even better if you generate a new ID for each download so that should you need to find the user who re-sold your files, you can prove when they downloaded it and from what IP address, along with any other information you wish to keep in your database.
MIDI Files
For MIDI, you will have to embed your ID in the metadata of the file. This can be easily defeated, and may not be worth your time at all.

Most elegant way to print differing file formats stored as BLOBs

I have a table with checkboxes that corresponds to BLOBs kept in MySQL database. These are all different types of files txt, xls, doc, pdf, etc. I am new to programming so I am not sure how to best allow my users to print these files in groups? I understand I cant control their hardware so I need to display these files in a window where they print the contents correct?
Should I somehow figure out how to display all the selected files in one pop up window or is that even possible? (eg user selects a .pdf and .doc file, do I try to get those two to display together and the user can print contents of that window? Maybe loop through and put them in divs something like suggested here? loading an external pdf document into div)
Or do I have to display each file in its own window and the user just selects print from that window? The user is going to think of the combined documents as one big package so the last suggestion is by far the least elegant. I guess I could just display each file in a separate tab so they can print, that is how it is setup now but I would like to display the files for print all together if at all possible. How has the community handled this in the past? Any advice for a beginner is appreciated.
I would think that for the purpose of keeping things less confusing for an end user, you'd want them to open in separate windows.
Your user will need some type of plugin in order to properly display a .pdf file however. As far as .doc, .xls, etc. files, you'll have to convert the file to a .html file so that it has some/most of the formatting, otherwise the users browser will ask them to open a local program to read the .doc file.
One option that would probably be the easier solutions, is have the server take the selections, convert the items to pdf files and then merge all of the pdf files. This would keep them sequential like you asked...all in the browser...and you could give the user the option to save the pdf file on their local machine if they want to.

Embed code in video file

I'm sorry if the question is ambiguous, I'll try to explain.
I'm working on an existing PHP download script for videos and some parts of it are broken. There's code in there that's supposed to place a specific member code inside the video file before download, but it doesn't work. Here's the code:
//embed user's code in video file
$fpTarget = fopen($filename, "a");
fwrite($fpTarget, $member_code);
fclose($fpTarget);
$member_code is a random 6-character code.
Now, this would make sense to me if it were a text file, but since it's a video file, how could this possibly work and what is it supposed to do? If the member code is somehow added to the video, how can I see it after download it? I have no experience with video files, so any help is appreciated (a modification of the available code or new code would be equally welcome).
I'm sorry I can't give a more precise description of what the code is supposed to do, I'm trying to figure that out myself.
It may work, depending on the format/type of the video. MPG files are fairly tolerant of "noise" in a file and players would skip over your code because it doesn't look like valid video frame data.
Other formats/players may puke, because the format requires certain data be at specific offsets relative to the end of the file, which you've now shifted by 6 characters.
Your best bet is to figure see if whatever format you're serving up has provisions for metadata in its specifications. e.g. there might be support for a comment field somewhere that you can simply slap the code into.
However, if you're doing all this for 'security' or tracking unauthorized sharing of the video, then simply writing the number into a header is fairly easy to bypass. A better bet would be to watermark the video somehow so that the code is embedded in the actual video data, so that "This video belongs to member XYZ only" is displayed while playing.
You don't write to the content of the file directly, not like you would with a text file. As you've noticed, this effectively corrupts the video and you have no way of reasonably reading the information.
For audio/video files, you write to meta-data that's packaged with the file. How this is packaged and what you can do with it generally depends heavily on the container format used for the file. (Remember that container and codec are two different things. The codec is the format used to encode the audio/video, the container is the file format in which that data stream is stored.)
A library like getID3 might be a good place to start. I've never used it, but it seems to be what you're looking for. What you would essentially do is write a value to the meta-data in the container (either a pre-defined value for that container or maybe a custom key/value pair, etc.) which would be part of the file. Then, when reading the file, you can get that data. (Now, that last part depends heavily on what's reading the file. The data is there, but not every player cares about it. You'll want to match up what you're writing to with what you usually see/read from the file's internal meta-data.)

Is there a way with PHP to access a file on a server and save only the first half of the file?

I want to give users a preview of certain files on my site and will be using scribd API. Does anyone know how I can access the full file from my server and save the file under a different name , which I will then show to users..Can't think of a way to do this with PHP for .docx and image files...Help is much appreciated.
For "splitting" images, use an image processing library like gd to crop the image (lots of examples to be found on how to do that all over the place). For Word documents, use a library like PHPWord (or one of the other myriad such libraries) to open the document, remove/extract as much text as you need, then save that into a new Word file.
For other file types, find the appropriate method that allows you to manipulate that format, then do whatever you need to do with it.

Storing image/data in MySQL and naming conventions

What are some ideas out there for storing images on web servers. Im Interacting with PHP and MySQL for the application.
Question 1
Do we change the name of the physical file to a000000001.jpg and store it in a base directory or keep the user's unmanaged file name, i.e 'Justin Beiber Found dead.jpg'? For example
wwroot/imgdir/a0000001.jpg
and all meta data in a database, such as FileName and ReadableName, Size, Location, etc.
I need to make a custom Filemanager and just weighing out some pros and cons of the underlying stucture of how to store the images.
Question 2
How would I secure an Image from being downloaded if my app/database has not set it to be published/public?
In my app I can publish images, or secure them from download, if I stored the image in a db table I could store it as a BLOB and using php prevent the user from downloading it. I want to be able to do the same with the image if it was store in the FileSystem, but im not sure if this is possible with PHP and Files in the system.
Keeping relevant file names can be good for SEO, but you must also make sure you don't duplicate.
In all cases I would rename files to lowercase and replace spaces by underscores (or hyphens)
Justin Beiber Found dead.jpg => justin_beiber_finally_dead.jpg
If the photo's belongs to an article or something specific you can perhaps add the article ID to the image, i.e. 123_justin_beiber_found_dead.jpg. Alternatively you can store the images in an article specific folder, i.e. /images/123/justin_beiber_found_dead.jpg.
Naming the files like a0000001 removes all relevance to the files and adds no value whatsoever.
Store (full) filepaths only in the database.
For part 2;
I'm not sure what the best solution here is, but using the filesystem, I think you will have to configure apache to serve all files in a particular directory by PHP. In PHP you can then check if the file can be published and then spit it out. If not, you can serve a dummy image. This however is not very efficient and will be much heavier on apache.

Categories