Keep track of user uploads within articles - php

just can't get my head around this.
I just finished my own WYSIWYG editor. It allows my users to upload images to embed in their article they are writing.
But how can i keep track of those user uploads ? I want them to be attached to the article, so that when i remove an article all images will also be removed. (keep my disk clean)
My first bet was to add an hidden input field to the article form for every uploaded image containing the image name, then on submit move all attached images from the tmp dir to the article image dir.
But this way a user can attach 100 times a picture to an article, remove them 99 times from the WYSIWYG editor and use only 1. Now i would have to save all the unused images. This seems like waste to me.
Any best practices on this ?

Don't worry about the edge case. Nobody is going to upload then deassociate 99 images.
You have to move the received files out of the tmp dir as soon as the (ajax?) upload sends them over. You cannot wait till the article submission, because the /tmp files would be gone by then.
Try to save your images with enumerated filenames like ArticleName.1.jpeg. And let your WYSIWIG editor inject uniqure placeholder tokens like {{img1}} on which you can see which images are factuall still in the article. (You can also try to deduce the file ids out from <img src="upl/articlename.1.jpeg"... since your WYSIWIG editor generates HTML.)
Anyway, on upload compare the list of enumerated {{img123}} tokens with the existing list of files.123.jpeg. Remove the unused.
Alternative: Do not remove unused images. Sell it as feature, since you now have more article history. And I guess the filesizes are negligible for most web sites.

Related

Implementation of fully functional media uploading in web application

Suppose we have the web application which handle create, read, update and delete articles and each article should have gallery of images. I have to make one to one relation between Article and Gallery and one to many relation between Gallery and Media.
HTML5 gives a lot of features like multiupload, so I want to use this excellent http://blueimp.github.io/jQuery-File-Upload/ plugin for that. The problem is how to handle the file upload "in memory" like other form's data?
For example when we show the page for create new article we should be able to fill in article's data fields and select images to upload, next when we click the save button the images should start upload and after that the form should submit. When validation fails the images should be still displayed on the frontend, but on the server-side nothink should be saved.
One of the solutions is create somethink like "create entity session temporary id" before displaying the entire form and that id can be used to create temporary directory for save uploads, so after success saved form these images can be moved to appropriate directory, but how to make the "create entity session temporary id"?
The other solution I think is the "with the edit id" approach, because we can handle the uploads with previously saved gallery id, but sometimes I can't save new blank article with gallery, cause some of the fields should't be empty in db.
For the Rails I saw https://github.com/thoughtbot/paperclip gem which in the Readme says:
Paperclip is intended as an easy file attachment library for Active Record. The intent behind it was to keep setup as easy as possible and to treat files as much like other attributes as possible. This means they aren't saved to their final locations on disk, nor are they deleted if set to nil, until ActiveRecord::Base#save is called.
My question is how it works?
The problem with enabling file uploads on the create mask is that you eventually end up with orphaned files. This is because a user is able to trigger the upload without saving the actual entity. While creating a very own UploadBundle I thought about this problem for a while and came to the conclusion that there is no truly proper solution.
I ended up implementing it like this:
Given the fact that our problem arise from orphaned files, I created an Orphanage which is in charge of managing these files. Uploaded files will first be stored in a separate directory, along with the session_id. This helps distinguishing files across different users. After submitting the form to create the actual entity, you can retrieve the files from the orphanage by using only your session id. If the form was valid you can move the files from the temporary orphanage directory to the final destination of your files.
This method has some pitfalls:
The orphanage directory itself should be cleaned on a regular basis using a cron job or the like.
If a user will upload files and choose not to submit the form, but instead start over with a new form, the newly uploaded files are going to be moved in the same directory. Therefore you will get both the files uploaded the first time and the second time after getting the uploaded files.
This is not the ultimate solution to this problem but more of a workaround. It is in my opinion however cleaner than using temporary entities or session based storage systems.
The mentioned bundle is available on Github and supports both Orphanage and the jQuery File Uploader plugin.
1up-lab/OneupUploaderBundle
I haven't work with the case personaly, but my co-worker had similar conundrum. She used
punkave/symfony2-file-uploader-bundle
It's a bundle that wrapps jQuery File Upload plugin. It is in the early stages and a lot of things are missing, such as event, but we gave it a shot.
That's what we do: in newAction() we create entity, generate unique dir ID, and store the ID in entity (via regular setDirId()). Than we create the form, which contains hidden field dirId.
We are uploading the files to temp dir on server via ajax, not during the submit. Ajax request requires the ID. It stores files in temp_dir/prefix_ID
Than it's quite simple. Form is sent. If form is valid - move files from temp to dest dir. If not - we have the ID, and are able to show the images.
However, we do not save information about individual files in a separate table in the database. Every time we read the contents of the folder that corresponds to our dirId.
I know it's not the solution You are asking for. It's rather a workaround.

Combine (merge) images with drag & drop

Image this scenario:
There is a picture locally in my server, where a sketch is displayed, and there is a "blank hole" area on it.
Then, a user can upload another picture to my server.
What i'm trying to achieve is this:
After image upload is finished, the first image (the one with the "hole") is displayed, and behind it is displayed the user's photo, so that you can see it through the "blank hole" area of the first photo.
Then the user can move his picture (drag & drop style) so he can choose which area of it is visible through the "blank hole".
Then i would like to save the result - by merging the 2 photos or keeping the position of the user's picture in a db so i can display it again later.
(Something like this more or less)
What kind of technollogy should i look for? I'd guess javascript(for the drag & drop) or html5 or php(for merging the photo)?
Are there any libraries that i can use?
I hope my explanation isn't too messy, i didn't even know how to google for it.
I don't know if there are better solutions (and I suspect there are), but I suspect all of this can be done with not too much trouble. Here's a rundown of one way to approach the problem:
Use a JavaScript-powered "upload widget" such as uploadify to enable your user to upload "his" image to the server. The server will do some processing on the image (e.g. resize and crop to suitable dimensions) and save it using e.g. PHP's gd library. It will return a URL to the "prepared" image back to the browser -- all of this through AJAX.
The browser then has a URL to the user's image, so using more Javascript you can dynamically add an element that displays it inside the page and allow the user to move it around with e.g. jQuery draggable. Compositing the draggable image behind your static content (the image with the "hole") is a detail you will have to take care of using a combination of HTML, CSS and again Javascript.
When the user is done, use an AJAX call (e.g. again jQuery) to inform the server of the image's positioning (this will be available through the facilities of the Javascipt framework you have selected). The server can then "compose" the two images together (gd or something equivalent once more) and return to the browser a URL through which the final product can be accessed.
Of course there are lots of details to take care of here, but knowing exactly what the plan is should help you get started.
Have a look at the PHP GD extension. If it's installed, it's pretty easy to have an image (with a transparent center) to be merged on top of a second image that a user would upload.
Have a look at http://php.net/manual/en/function.imagecopymerge.php
Ok to get you started, yes use a JavaScript drag and drop module for the placing of the image. You can record the x /y cordinates relative to the container. Do the image merging with a PHP image library / Class. Something like this : http://www.phpclasses.org/package/3930-PHP-Generate-an-image-from-the-combination-of-2-images.html

what are the best practices for letting users upload theme files to my server

I'm trying to make my own framework for my own projects and I would want people to upload themes for their profiles to the database. Letting them theme the look and feel of their accounts.
I first thought of having the files on the server.
A user would log in and the PHP would pick up their user id and other misc details and route the urls to their particular folder and serve the files in that folder.
an example would be a real directory of
http://www.foo.bar/users/me/style.css
http://www.foo.bar/users/me/script.js
http://www.foo.bar/users/me/index.tpl
http://www.foo.bar/users/me/otherPage.tpl
then I was thinking wow, imagine if I have 100's of users? then I would have 100's of folders in my users directory on my server, not to mention duplicate files all over the place taking up space. So ok, while this may be the fasted way to fetch a file maybe loading the markup from the database won't be such a bad idea right?
My server looks cleaner but now my database will get queried a lot more than I would want.
Then comes the major issue i think, is having files that are particular to a user. For example stylesheets may have background url's with images, so now these images needed to be linked to their real path on the server. Which brings me back to having a dedicated folder for each user to house their theme specific files.
How can i securely and effectively find a way to let users upload themes and have all files images, pdf's, docs, etc. all saved without them potentially being accessed by another account holder or thru simple hacking techniques to pull a file from the server that belongs to another user.
One solution I thought of was to only let users who are logged in view files, append to the file a unique tag that will let the user view the file if the tag matches a session variable. But then what if a user wants to share that file with another person, then tagging the file would bring my back to square 1 with the security thing not letting view the file because they wouldn't be an authorized user.
Well in any case, what would be best practices to get some of my concerns on the right path to being delt with.
P.S.
I choose these tags because in my solutions I think they will touch upon some of these aspects.
You can store html or css in a table row but be sure to sanitize the data to avoid hacks, or injections. The easiest way would be to let the user paste the code into a text area or field. If you want to let them upload files, you will need to write a script that parses the data from the uploaded file. This is more complicated as you will have to manage all filtering and sanitizing along with making pulling the data from the file and saving it to the database.
We skin our CMS to work with multiple clients and their own users. But rather than giving them the possibility of changing ANY area or style of the page we allow certain areas such as:
upload your logo
set the colour of the banner bar behind your logo (using a smart colour picker and some 'figure out the contrast between the colours' functions)
set your text colour (using a colour picker)
and so on for the items you want them to change.
We then store those in the database and serve them up through dynamic stylesheets (I know these don't cache but it's better than having hundreds of files).
I know that MySpace used to let you upload a whole host of HTML and CSS (not sure if they still do) but it's a security nightmare as the potential for XSS is enourmous.
You may want to look at HTML Purifier if you're going to let them add their own custom HTML and full themes -> http://www.htmlpurifier.org

A good solution for displaying galleries with lytebox and php

I have thought for a while over an issue with the loading of images on a website-solution that I have programmed (For fun and the experience)
The programming language used is PHP with MYSQL as the database language
It also uses javascript, but not extensively
I have recently realized that the engine I programmed, while it has it's smart solutions also carry a lot of flaws and redundant code. I have therefore decided to make a new one, now incorporating what I know, but didn't when I started the previous project.
For the new system, there will be an option to add galleries to a site, and upload images to it. I have used the javascript image viewer Lytebox before. The screen goes dark and an image appears with a "Previous" and "next" button to view the other images.
The problem is that I used groups with lytebox and the images themselves, resized as thumbs. This causes lytebox to work only when all the images have loaded. If you click a link before that, the image is shown as if you right click and choose "Show image"
Information about these images is parsed from a database using a while statement with a counter that goes from 0 to sizeof()
I'm thinking it probably isn't a good idea to have the images as the thumbs, even if you restrict the upload size. Likewise, adding thumbs at upload also seems like a hassle. It would be practical if the thumbs didn't show up before they were fully loaded.
Has anyone got any good tips. Any help would be appreciated.
Johann
Not really. What I would like to know is what route to go when creating a page that lets you upload images. Does other systems usually create thumbs-files when a user uploads a file? Is there a way to display images on the server as thumbs that doesn't require you to load the entire image?
What would also work would be to get lytebox to pop up, with a white frame and "wait" for the image. Basically everything else than opening the image as a regular link.
I had an account here before, seems like it has been reset or something. Tried logging on with both google open-ids. Wouldn't let me comment your comment so I had to do it the hard way and answer my own post :|

Image manipulation with JQuery and PHP

I want to do some kind of image editor, after I upload more images I make a list with all the thumbnails!
After, I want to be able to click on one thumb and rotate, duplicate, drag and drop (to change positions of the images), and delete the image. I want all the images to be in a php array. If an image is deleted I want to delete the row from array too. If a image is drag-and-dropped I want to change the position in the array too.
Ok, after the user uploads all the images and modifies some of them, how can I make a DONE button to save the positions of the images?
I made all ready all this, i only need to know how i can save the list of images after i "edit" with jquery? i need a save button or something
For this small project how do you suggest I save the images? (to make a table in mysql and store the names of the images in the database depending on the session id? depending on the IP?)
Any suggestions are welcome!
Way, waaay too all-encompassing question.
My suggestions:
Get familiar with gd or ImageMagick
Get familiar with jQuery UI, especially the drag & drop functionality
Store images in a temp folder on disk
Write a caching mechanism around it that'll clear the folder of unused images in regular intervals
Hashes can help to retrieve images from cache
Store state in a session
Do some work on this and come back with more specific questions.

Categories