CodeIgniter upload image through tinymce - php

I'd like some help please. I have created a form with CodeIgniter where I can write posts and what I 'd like to do is to add the functionality to upload image(s) for this post.
At the beginning I thought to add an input field in my form where I can upload files, so I can display them above the content (text) at the front end, but although this is a very quick and easy solution, may be not so flexible. So I thought to use the 'insert/edit image' button that tinymce has.
I haven’t done this before so how can I upload an image or images through tinymce so that they appear within the text at the front-end??
EDIT Here is my code.
This is my view:
<?php echo form_open_multipart(); ?>
<div>
<label for="title">Title *</label>
<?php echo form_input('title', html_escape(set_value('title', $article->title))); ?>
</div>
<div>
<label for="file">Upload image</label>
<?php echo form_upload('file'); ?>
</div>
<div>
<label for="body">Body *</label> // has TinyMce
<?php echo form_textarea('body', strip(set_value('body', $article->body))); ?>
</div>
<div>
<?php echo form_submit('save', 'Save'); ?>
</div>
<?php echo form_close(); ?>
This is my model:
public function save($id = null){
$post_data = array(
'title' => $this->input->post('title'),
'file' => $this->input->post('file'),
'body' => $this->input->post('body'),
);
return parent::save($post_data, $id);
}
This is the controller:
public function article($id = null){
....
$this->form_validation->set_rules($this->article_model->rules);
// Process the form
if ($this->form_validation->run() == TRUE) {
$this->article_model->save($id);
redirect('admin/article');
}
}

There are two approaches to this.
You either keep an upload field outside TinyMCE and use ajax/iframe file upload.
OR
Write a TinyMCE plugin with an ability to upload an image.
Please note that both of these approaches take some effort to implement.
As far as handling the file on the server side is concerned, you can go through the Codeigniter Docs to get you started.

In my opinion , I think that you should use separate field to upload images to server as this helps you control them , resize , determine file name and upload path
you can use form_open_multipart() Codeigniter function to upload files
then you can make a DB table field called image and insert the uploaded file name to it
then retrieving the post you can
<img src="<?php echo $post->image; ?>" />
<p><?php echo $post->content ?></p>

Related

Codeigniter file upload from a form without ajax/jquery/javascript

Context : I am updating user_profile data after user registration using form #updateprofileform ,
i am able to process all other form fields using standard validations and insert/update using user_model.
issue is with resume field which should accept a file as input type and upload to server and store its path on server (say http://domain/uploads/$filename) to a column in database.
Expectation A logged in user , able to view his details(if already in database),update details if incomplete profile.
Question : I found methods how we can upload a file to server using CI framework or how we can upload a file in this context using jquery/ajax/java-script. But i am looking for simple solution for above problem which can do the job with out dependency on technologies.
user_profile.php (view)
<table>
<form class="row" name="updateprofile" action = "<?php echo base_url()?>user/user_profile" method="POST">
<tr>
<td><label for="email">Email ID</label></td><td><input class="form-control" name="email" placeholder="Email-ID" type="text" value="<?php if (isset($email)) echo $email;?>" /> <span style="color:red"><?php echo form_error('email'); ?></span></td>
</tr>
<tr>
<td><label for="resume">Resume</label></td>
<td>
<input name="resume" placeholder="Upload resume" type="file" value="<?php if (isset($resume)) echo $resume;?>" />
<span style="color:red"><?php echo form_error('resume'); ?>
</span>
</td>
</tr>
<tr>
<td></td>
<td><div class="col-md-6 col-lg-3"> <button type="submit" class="btn btn--primary type--uppercase" name="updateprofile" value="updateprofile" formaction = "<?php echo base_url()?>user/user_profile">Update Profile</button> </div></td>
</tr>
</form>
</table>
user_controller
class User extends CI_Controller {
public function __construct()
{
parent::__construct();
$config = array(
'upload_path' => "./uploads/",
'allowed_types' => "doc|docx|pdf",
'overwrite' => TRUE,
'max_size' => "2048000", // Can be set to particular file size , here it is 2 MB(2048 Kb)
//'max_height' => "768",
//'max_width' => "1024"
);
$this->load->library('upload', $config);
}
public function user_profile()
{
$resume = $this->input->post('resume');
if ($this->user_model->set_user_profile($id,FALSE) )
{ if($this->do_upload($resume)){
$this->session->set_flashdata('msg_success','Updation Successful!');
echo validation_errors();}
}
else
{
$this->session->set_flashdata('msg_error','Error! Please try again later.');
redirect('user/user_profile');
}
public function do_upload($resume){
if($this->upload->do_upload($resume))
{
$data = array('upload_data' => $this->upload->data($resume));
$this->load->view('user_profile',$data);
}
else
{
$error = array('error' => $this->upload->display_errors($resume));
$this->load->view('user_profile', $error);
}
}
currently always error.... Error! Please try again later . so appreciate some pointers here to upload both file and form data together and save file location in database without ajax/jquery.
Thanks
Change the form definition to the following:
<form class="row" action = "<?php echo base_url('user/user_profile'); ?>" method="post" enctype="multipart/form-data" name="updateprofile" >
Resolved !
4 important steps needed and some missing in most Q&A in all other posts to make this complete.will share samplecode in github when i get sometime.
form encryption type must be enctype="multipart/form-data" (thanks
to #Javier Larroulet and #dexter )
do_upload method by default look for file field with name=userfile
(Thanks to #Alex ! for referencing this), so, if you have your
form's file field name different than userfile, then only it is
required to mention as do_upload('filefieldname') otherwise
optional
loading of upload library configuration is tricky.. if you
autoupload the upload library , then load->library upload config will fail!, you
just =>initialize it.$this->upload->initialize($config); if you
are not using autoload for upload library, then yes, you can load it
from controller. $this->load->library('upload', $config);
when ever, you are using upload, you have to catch the form validation errors
and data errors separately (again thanks to #Alex for pointing this)
a nice documentation is given from codeigniter at this link (https://www.codeigniter.com/userguide3/libraries/file_uploading.html#the-controller ) but doesn't highlight routine mistakes.
hope this post help someone not to waste another 24 hours to debug.

Retrieve Images From Folder with Codeigniter

My teacher,he was uploading and retrieving images from folder with ID recognition. It works with database.
So, when we upload an image, it will be stored in a folder with it's name changing automatically with ID.
Example: The upload form must be on "yourwebsite.com/yourpages/3144242" so the image will be stored as "3144242" and blablabla the same for other pages with ID
This is how he upload and retrieve it
<?php
$ff = './assets/images/kegiatan/'.$_SESSION['idkeg'].'.jpg';
if( file_exists( $ff ) ) {
<img src="<?= base_url()?>assets/images/kegiatan/<?=$_SESSION['idkeg']?>.jpg" />
<?php
}
?>
Retrieve images part:
if( file_exists( $ff ) ) {
<img src="<?= base_url()?>assets/images/kegiatan/<?=$_SESSION['idkeg']?>.jpg" />
<?php
}
?>
However, I change it a bit so I don't have to use a database and $_SESSION things. With this:
<?php
$ff = './assets/images/kegiatan/'.$this->input->post('img_name').'.jpg';
?>
<form id="form" class="kart" action="<?= base_url()?>gallery/upload2" method="post" enctype="multipart/form-data">
<div class="form-group">
<input type="text" class="form-control" name="img_name" required="required">
</div>
<div class="form-group">
<input type="file" class="form-control" name="foto">
</div>
<div class="form-group">
<button type="submit" class="btn btn-common" value="Update"><i class="fa fa-upload fa-2x"> Upload</i></button>
</div>
</form>
It works uploading images into folder "kegiatan" (means activity) with simply write the names of images in a form. The img_name that you have input, now become the name of that image.
Now I have a little problem to retrieve that images. How?
mistake in your form I realized is asking user to enter image name and get image from folder by using that input value.
First of all, I haven't tried upload an image with codeigniter but I will answer reference to php itself.
When we get an image as input from user by form, then we use "move_uploaded_file" function in php and we send temp_file, path with file name arguments to this function to save the file user selected in the form we prepared.
move_uploaded_file(string $filename , string $target);
// $filename: I use $_FILES['getFileUpload']['tmp_name'] for this argument
// $target: I define path with file name, eg: uploads/files/new_file_25.jpg for jpg image
So, you souldn't ask user to enter file name, because you will deifne it. Or, you must use "img_name" that you asked user to enter as file name which is most probably won't satisfy your ID prediction.
I hope this will help you.

Is it possible to show a image that is in a tmp folder before upload?

I want to show the user a image before the user uploads it to the server to make sure that this image is what the user wanted to upload.
I have tryed to do this with $_FILES['name']['tmp_name'] and put this in a tag but nothing happens.
<form action='' method='POST' enctype="multipart/form-data">
<header class='pageHeading'>Kop afbeedling toevoegen</header>
<section class='body'>
<div class='inputFrame'>
<img src="<?php if(isset($_FILES['image']['tmp_name'])){echo $_FILES['image']['name'];}?>"/>
<div class='input'>
<div class="cellFrame">
<div class="inputHeading">Afbeelding uploaden</div>
<div class="frame">
<div class="frameAlign">
<div class="displayFlie">
<input type='file' name='image'/>
</div>
<button name='upload' class='btnUpload btn'>Upload</button>
<div class="clr"></div>
</div>
</div>
</div>
</div>
<div class="clr"></div>
</div>
</form>
simple solution - grab your image data convert to base64 and output in your current view, so you don't need to copy the current tmp image into an public loction- like
$imageData = file_get_contents($_FILES['image']['tmp_name']); // path to file like /var/tmp/...
// display in view
echo sprintf('<img src="data:image/png;base64,%s" />', base64_encode($imageData));
After the image is submitted, it's already uploaded to the server in a temporary file. If you need to show the contents of the image from that temporary file, then you need to do a script that reads that file and outputs it with the right headers. Here's an example:
header('Content-Type: image/x-png');
readfile($_FILES['name']['tmp_name']);
exit();
any files uploaded to the server if not moved will be deleted automatically.
but do not worry. before uploading, you can display it using javascript or jQuery.
<form>
<input type="file" accept="image/*" name="" onchange="previewImage()">
<img id="preview">
</form>
<script>
function previewImage(){
var previewBox = document.getElementById("preview");
previewBox.src = URL.createObjectURL(event.target.files[0]);
}
</script>
Have you tried reading the file directly from the /tmp folder? Of course this can only happen after the upload, not before. So you have to do this before moving the file to its destinated folder, but right after the upload.
readfile($_FILES["name"]["tmp_name"]);
You have two ways of doing this.
The first is using a javascript code to show the preview before uploading to server, you can check this answer: Image Upload with Preview and Delete
The second one is to upload the image and retrieve a thumbnail from server to show in clientside, you can check this post: http://www.sitepoint.com/image-upload-example/
Yes, it is possible to show the image in the tmp folder. Add an onchange event for input type = file; which triggers a function and it loads the image.
!!! Don't forget to set width for img tag
function preview() {
$('#frame').attr('src',URL.createObjectURL(event.target.files[0]));
}
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
<form>
<input type="file" onchange="preview()">
<img src="" width="100px" height="100px" id="frame">
</form>
</body>

Sending Errors Back to Form: Code Igniter

I'm having trouble getting the form validation library to send my form errors back to my form in this case.
I have a controller that handles uploading images called addImage.php. This controller only handles the do_upload processing. I have a view called uploadimage.php that contains the upload form and submits to /addImage/do_upload.
The upload form is loaded on the front page of my website using a template in code igniter using
<?php $this->load->view('uploadimage'); ?>
The front page controller is contained in home.php
Right now after validation fails, I'm just redirecting to the homepage which clearly doesn't load the errors back (in addImage.php)
if($this->_submit_validate() == FALSE)
{
redirect('/', 'location');
return;
}
How can I redirect to my template_front.php while keeping those errors. Can I somehow call my home.php controller from the uploadimage.php controller to do this? I've confused myself trying to explain it! If this is totally unclear, let me know and I'll try to clarify.
Per the Documentation, you are suppose to simply re-load the view file on failure.
if ($this->form_validation->run() == FALSE)
{
$this->load->view('myform');
}
else
{
$this->load->view('formsuccess');
}
a redirect generates a new server request which flushes the validation error information.
on validation failure you should reload the form. May be you want to add a button to concel uploading.
On the view, you should add some tag to show errors (there are lots of info about validation helpares) like in:
<?=form_open_multipart("/personas/savefoto", array('class' => "form3") )?>
<h3><?=$heading?></h3>
<div class="center">
<?php echo '<strong>'.mb_convert_case($record['nombre'].' '.$record['apellido1'].' '.$record['apellido2'], MB_CASE_TITLE).'</strong><br/>';
if( file_exists("fotos/e".MATRIZ."/b".$record['id'].".jpg")){
?>
<img class="foto" src="<?php echo base_url()."fotos/e".MATRIZ."/b".$record['id']?>.jpg"/>
<br/><br/>
<?php
} ?>
</div>
<div class="form-row">
<label for="imagen">Nueva imagen <br/>(jpg, gif o png)</label>
<input type="file" name="userfile" size="20" />
<br/>
<?php if(isset($error_image)) echo '<p class="error">'.$error_image.'</p>'; ?>
</div>
<div class="form-row center">
<input type="submit" value="Aceptar" />
<input type="button" value="Cancelar" onclick="location.href='/system.php/personas/admin';">
</div>
<?=form_close();?>
look for the if(isset($error_image))
You could utilize the validation_errors() function and set them to a session variable
$this->session->set_userdata(array('form_errors', validation_errors()));
then access them on your redirect page.
echo $this->session->userdata('form_errors');
$this->session->unset_userdata('form_errors'); // prevent them from being stored past use

Add HTML placeholder into Zend_Form

I'm using Zend_Form for an application form using this code:
class Form_ApplicationForm extends Zend_Form
{
public function init()
{
$this->setAction('/application/new')
->setMethod('post')
->setAttrib('id','application');
$name = new Zend_Form_Element_Text('name');
$name->setLabel('Your Name')
->setRequired(TRUE)
->addValidator('alpha', FALSE, array('allowWhiteSpace' => true));
$email = new Zend_Form_Element_Text('email');
$email->setLabel('Email Address')
->setRequired(TRUE)
->addValidator('EmailAddress');
$this->addElements(array($name,$email));
}
}
I'm adding a flash file uploader (swfupload) to this form which needs a HTML snippet to be in place to work, the snippet looks like this:
<div id="swfupload-control">
<p>Upload upto 5 image files(jpg, png, gif), each having maximum size of 1MB(Use Ctrl/Shift to select multiple files)</p>
<input type="button" id="button" />
<p id="queuestatus" ></p>
<ol id="log"></ol>
</div>
What is the best way of inserting this so that it sits somewhere within the <form> which i'm inserting within my controller like this:
public function newAction()
{
$form = new Form_ApplicationForm();
if($this->_request->isPost()){
$data = $_POST;
if($form->isValid($data)){
/// handle data here
}else{
$form->populate($data);
}
}
$this->view->form = $form;
}
Is there a way of adding a placeholder or similar within Zend_Form, or should this be done using a decorator or something like that?
Thanks.
You'd have to write your own Element for this, e.g. My_Form_Element_SwfUpload along with a renderer. See these tutorials:
The simplest Zend Form Decorator
How to layer Decorators
Rendering Zend Form Decorators individually
Creating composite elements
The simplest way is to do it in the view:
By echoing each element you can print its html. Here's one way to do it:
<form id="<?= $this->form->getId() ?>" action="<?= $this->form->getAction() ?>">
<? foreach ($this->form as $element): ?>
<?= $element ?>
<? if ($element->getName() == 'email'): ?>
<div id="swfupload-control">
<p>Upload upto 5 image files(jpg, png, gif), each having maximum size of 1MB(Use Ctrl/Shift to select multiple files)</p>
<input type="button" id="button" />
<p id="queuestatus" ></p>
<ol id="log"></ol>
</div>
<? endif ?>
<? endforeach ?>
</form>
What this does is it prints all the elements, and puts whatever you have to after the email field. If you add or remove a field from the form this code will continue to work (of course it will fail if you remove the email field).

Categories