So, i want to make if user click the delete button the picture profile will be user.jpg (this is default picture).
enter image description here
here is my controller :
public function update()
{
$fileimg = $this->request->getFile('img');
$oldimg= $this->request->getVar('oldimage');
$defaultimg= $this->request->getVar('defaultimage');
if ($fileimg == 'user.jpg') {
$uploadImg = $defaultimg;
}
if ($fileimg->getError() == 4) {
$uploadImg= $oldimg;
} else {
$uploadImg = $fileimg->getRandomName();
$fileimg->move('img/', $uploadImg);
if ($oldimg != 'user.jpg') {
unlink('img/' . $oldimg);
}
}
When i click delete button image the image will be user.jpg and then i click button upload but the image wont change to user.jpg, but always showing the old picture.
sorry for bad english.
How about think like this:
Default picture is not a data which user is willingly save to database. It's rather a placeholder. Thinking further, it can be handled in the views. If user profile picture is not set or exists, show default picture. To prevent typing manually you can make it a global data or a config value or a constant. But the key is it is a placeholder, not a data.
Happy coding...
Write the image name in a database somewhere, usually in the user profile table. It will make your life much easier, and you'll be able to access it all the time. Then in your model, you'll be able to see if there is no image and return the default image.
I am not sure what your getRandomName() is doing, but some hash function (sha1, md5...) are good enough for creating a file name to avoid possible name collisions.
Related
I use Laravel 4.
I have a download button in my view.
I have a lot of users that have the access to see/click to download from that button.
Here is my question,
is there any way to keep track of how many time my file has been downloaded and by whom ?
Let’s say,
user A download 27 times
user B download 5 times
user C never download at all
user D download 200 time
so on and so forth …
My Controller Function
public function file_download($id)
{
$catalog_download = CatalogDownload::findOrFail($id);
$distributor = Auth::user()->distributor()->first();
$export_type = $distributor->export_type()->first();
$product_export = $catalog_download->product_exports()->first();
$destinationPath = base_path().'/app/files/product_export/'. $catalog_download->id.'/'. $export_type->id.'/';
$file_name = $product_export->file_path;
$pathToFile = $destinationPath .$file_name;
return Response::download($pathToFile);
}
In your database
You should create another attribute. Let’s called it download_count
integer
Set default to 0
In your controller function, at the end, just do.
$user->download_count = $user->download_count +1;
$user->save();
Every-time,the user trying to download sth, they will need to go through that function - right ?
Just increment(+1) it, every-time, they go through it. I hope I am clear enough. Good Luck :)
Just add an ajax call with the username and the downloadfile's name as the Ajax call 's data to the button and safe every click on the button to the DB. Then you can simply query for the file and user combination and you will get the number of downloads.
Other way would be to add the save function to your controller and save above mentioned combination through the controller
The only option I can think of is to store it in the database.
Once the user clicks the download button, add +1 in the database.
If I upload a file with YII and another rule fails, then the user has to pick the file again. What is the easiest way to avoid this?
For example, I have a rule that the title must be 20 characters at most. The user types in 21 letters. He chooses a file to upload. When the user is returned to the page, the file is no longer there and he must choose it again, and effectively upload it again. This is very frustrating, especially now when the user will be required to upload up to ten files.
I know Drupal works like this. If you upload and other rules fail, the files appear as screenshots when you return to the form. How can I get the same functionality on YII?
UPDATE
If I could get that requirement covered with this extension and not require that the user presses start upload, I would be home free
The original plugin that xupload wraps, there is an additional callback option you could use: .done().
In the xupload wiki, the way to access those additional options would be this way:
<?php
$this->widget('xupload.XUpload', array(
// ... other attributes
'options' => array(
//This is the submit callback that will gather
//the additional data corresponding to the current file
'submit' => "js:function (e, data) {
var inputs = data.context.find(':input');
data.formData = inputs.serializeArray();
return true;
}"
),
));
?>
Source
You could probably just change the submit part to done, and let that save the URL/path of the uploaded file to a temporary hidden field, and move your validation to that hidden field instead, so the user does not have to re-upload a file again.
I moved away from this plugin to the coco uploader as it was easier to implement.
You could enable client side validation and AJAX validation. So your regular attributes will be validated before the form is sent and the file gets uploaded.
You can do it with session.
In your controller
// Here I have taken Users as model. you should replace it as your need.
$model=new Users;
if(isset($_POST['Users']))
{
$model->attributes=$_POST['Users'];
//save file in session if User has actually selected a file and there weren't any errors.
if(isset($_FILES['Users']) && $_FILES['Users']['error']['image'] == 0){
Yii::app()->session['image'] = $_FILES['Users'];
}
if(isset(Yii::app()->session['image']) && !empty(Yii::app()->session['image'])){
$model->image = Yii::app()->session['image'];
$model->image = CUploadedFile::getInstance($model,'image');
}
if($model->save())
{
if(!empty($model->image)){
$model->image->saveAs(Yii::app()->basePath.'/images/'.time()."_".$model->image->name);
unset(Yii::app()->session['image']);
//File has successfully been uploaded.
}
// redirect to other page.
}
}
else{
// remember to unset the session variable if it's a get request.
unset(Yii::app()->session['image']);
}
And in your view file
//Your form fields
//This is to show user that he has already selected a file. You could do it in more sofisticated way.
if(isset(Yii::app()->session['image']) && !empty(Yii::app()->session['image'])) {
echo "<label>".Yii::app()->session['image']['name']['image']."</label><br>";
}
//File uplaod field.
//More form Fields.
Hope that helps.
I have a page with a form where user can upload an image to replace his existing avatar.
However, if the user submits forms without uploading an image, I will not update his avatar and user can keep his old avatar.
This is an UPDATE issue so I need something like this in pseudo code:
if (Input::has_uploaded_file() === true)
//User uploaded something, update avatar column/remove old avatar etc.
else
//User didn't upload anything so don't update avatar column
I just need the first line, though.
Can anybody help? I couldn't find much about this in documentation.
If Input::has_file('name') does not work for you then you can use the equivalent of what it is doing, like this...
if (Input::file('name.tmp_name', '') != '')
Taken from laravel/input.php
I read laravel source code, i think its this:
Input::has_file('input_name');
If that's not work, try using native php:
$_FILES['input_name']['error'] = UPLOAD_ERR_NO_FILE;
Or same above with laravel:
$i = Input::file('input_name');
$i['error'] = UPLOAD_ERR_NO_FILE;
Code above is to check if user leave the upload form empty.
I am using codeigniter + grocerycrud. I have a callback for image uploads.
I upload one image in the form, but want to do this:
copy it 3 times
resize each one a certain size
then save each one in the database.
any ideas how to do this? The callback only seems to let me edit the image (and do things like that) - not change the varaiables of the submitted data so we can save the manipulated data.
looking at their callback tutorial it looks like most call backs do something like this:
function callback_for_this_field($posted_data) {
$posted_data = $posted_data .= "append me";
return $posted_data;
}
(ie returning the modified data)
but the upload callback just returns true
You can simply do it with a callback_before_insert and callback_before_update. When a file is uploaded in grocery CRUD then a hidden field with value as the name of the file is inserted. So for example let's say you have:
$crud->set_field_upload('image_url','assets/uploads/images');
You can simply do something like this:
$crud->callback_before_insert(array($this,'_append_uploaded_file'));
$crud->callback_before_update(array($this,'_append_uploaded_file'));
and in your Controller add something like:
public function _append_uploaded_file($post_array)
{
if (!empty($post_array['image_url'])) {
$post_array['image_url'] = "append-me-".$post_array['image_url'];
}
//You can add or insert to other tables too
return $post_array;
}
Of course you can do the same thing with callback_after_insert and callback_after_update without any problem.
Am fairly new to PHP and am making a basic CRUD style management system. I Have an update page and it displays data from a News table, and populates a form with it. The current picture ?(reference) is pulled through and displayed on the form. However if a user wants to change the picture they can press a 'delete' button and then I have written some PHP to display a upload button, set the values in the database for the image to null and hide the delete button, allowing the user to upload a new picture.
The Delete button only removes the reference (path) to the picture from the database, it doesn't delete the actual picture.
This is the HTML control to show the image and delete button. It also shows how the delete button works:
<td align="right">Image 1:</td>
<td align="left"><img src="uploads/newsimages/<?php echo $row["Image"]; ?>" width="230" border="0"> delete</td>
As you can see, when clicked it sets change=imagex and cid= the current news id.
There is then an if statement I have written, but it doesn't seem to only get activated when the delete button is clicked. Because I always get an error that 'cid' is undefined. It is as follows:
<?php
if (isset($_GET['change'] = "image1") {
$query = "UPDATE Table_Name SET Image = '' WHERE NewsID =".$_GET['cid']." ";
}
?>
I am pretty sure my lack of PHP knowledge is letting me down and I am trying to go about this the wrong way, because however I alter the if statement it always gives me an error. First it was cid is undefined so I changed to id but i already use that for something else, another query/function. I hope that all amde sense, can anyone tell me where Im going wrong?
You are missing a parenthesis + you have to specify individually:
if (isset($_GET['change'] = "image1") {
Change to:
if (isset($_GET['change']) && $_GET['change'] == "image1") {
Some more things to consider:
1) Don't use unsanitized values directly from $_GET in a mysql query
WHERE NewsID =".$_GET['cid']."
It is very easy to exploit this with some funky sql injection (see http://xkcd.com/327/ ).
If you are using numeric values for cid, you should cast your $_GET value to integer to prevent sql injection:
$cid = (int)$_GET['cid];
$query = '(...)WHERE NewsID = '.$cid.' limit 1';
Or even better:
$cid = (int)(array_key_exists('cid', $_GET) ? $_GET['cid'] : 0);
if ($cid) {
$query = (...)
}
If you need this kind of sanitizing in different places, you should think about writing a helper function for it to keep your code readable.
2) Don't use GET requests to change data on your server
Imagine a google bot browsing your site and following all those links that you use to delete images. Other scenarios involve users with prefetch plugins for their browsers (e.g. Fasterfox). Also, GET requests may be cached by proxies and browsers, so that the request won't hit the server if you click the link.
The HTTP specification comes with numerous request methods, the most important ones are:
GET to fetch content from the server
PUT to store new information on the server
POST to update existing information on the server
To update your news record (by removing the image) the appropriate method would be POST. To send a POST request, you can use the <form method="POST"> tag.
try this
<?php
if (isset($_GET['change']) && $_GET['change'] == "image1") {
$query = "UPDATE Table_Name SET Image = '' WHERE NewsID =".$_GET['cid']." ";
}
?>