Codeigniter - Issue while uploading png image - codeigniter-3

I have implemented a web service for update profile image using Codeigniter framework. But I have an issue while uploading png image. It always gives an error saying -
The filetype you are attempting to upload is not allowed.
Following is my config array:
$config = array(
'upload_path' => BASEPATH .'../assets/uploads/profile_images',
'allowed_types' => 'jpg|png|jpeg',
'overwrite' => TRUE,
'max_size' => "2048000",
);
I have added "png" in allowed types, still it is showing error.
Please guide.

Instead of using
config['allowed_types'] = 'jpg|png|jpeg'
I changed my config array to
$config = array(
'upload_path' => BASEPATH .'../assets/uploads/profile_images',
'allowed_types' => '*',
'overwrite' => TRUE,
'max_size' => "2048000",
);
And added custom form validation rule
$this->form_validation->set_rules('profile_image', '', 'callback_file_check');
and its corresponding function named file_check(). Here I will be checking file type and will return an error if it is not an image.
/**
Function: file_check
Description: file value and type check during validation
Date: 6th July 2018
**/
public function file_check($str)
{
$allowed_mime_type_arr = array('image/gif','image/jpeg','image/pjpeg','image/png','image/x-png');
$mime = mime_content_type($_FILES['profile_image']['tmp_name']);
if(isset($_FILES['profile_image']['tmp_name']) && $_FILES['profile_image']['tmp_name']!="")
{
if(in_array($mime, $allowed_mime_type_arr))
{
return true;
} else {
$this->form_validation->set_message('file_check', 'Please select only jpg/jpeg/png file.');
return false;
}
}else{
$this->form_validation->set_message('file_check', 'Please choose a file to upload.');
return false;
}
}
So my upload function will look like this
if($this->form_validation->run() == true) {
if (!$this->upload->do_upload('profile_image')) {
return $this->response(['msg'=>$this->upload->display_errors(),'success'=>false,'code'=>400]);
} else {
$fileName = $this->upload->data();
$name = $fileName['file_name'];
}
//Save into database
$image = $this->Api_model->update_profile_image('assets/uploads/profile_images/'.$name, $request_data['user_id']);
if($image)
return $this->response(['msg'=>'Image updated successfully','success'=>true,'code'=>200, 'image_path' => base_url().$image]);
else
return $this->response(['msg'=>'Image updated failed','success'=>false,'code'=>400]);
} else {
return $this->response(['msg' => validation_errors(), 'success' => false, 'code' => 401]);
}

Related

How can I save url and local images?

I'm working on a project that uses the Spotify API. I get all the top tracks and top artists from users. I save the information into my database, the image that I get from Spotify is a URL image. Like this https://i.scdn.co/image/ab67616d0000b27300d5163a674cf57fe79866a6
In my CMS I want to be able to change the image of an artist or track. For this, I copied the code from the docs https://backpackforlaravel.com/docs/4.1/crud-fields#image-1 "public function setImageAttribute($value) and put this in my model. Everything is working fine for this part, I can upload a new image and it saves into my public folder and gets displayed in my table.
The problem that I have is that when a new user logs in and the artist/track data needs to be saved in the database it goes through this setImageAttribute($value) in the model and doesn't add the URL into the database column.
Is there a way that I can add the URL image without going through the setImageAttribute function in the model?
The controller:
//get Top Artists
$client = new Client([]);
$topartists = $client->get('https://api.spotify.com/v1/me/top/artists?time_range=medium_term&limit=25&offset=5', [
'headers' => [
'Authorization' => 'Bearer ' . $token,
],
]);
$listtopartists = json_decode($topartists->getBody(), true);
$p = 25;
foreach ($listtopartists['items'] as $topartist) {
$artist = TopArtist::where('artist_id', $topartist['id'])->first();
$artist_genre = json_encode($topartist['genres']);
if ($artist === null) {
$new_artist = TopArtist::create([
'artist_id' => $topartist['id'],
'name' => $topartist['name'],
'genres' => $artist_genre,
'users_popularity' => $p,
'popularity' => $topartist['popularity'],
'image' => $topartist['images'][0]['url'],
'url' => $topartist['external_urls']['spotify'],
]);
$spotify_user->topArtists()->attach($new_artist->id);
} else {
$exists = $spotify_user->topArtists()->where('spotify_user_id', $spotify_user->id)->where('top_artist_id', $artist->id)->get();
if ($exists->isEmpty()) {
$spotify_user->topArtists()->attach($artist->id);
}
}
$p--;
}
The Model:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;
class TopArtist extends Model
{
use \Backpack\CRUD\app\Models\Traits\CrudTrait;
use HasFactory;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'artist_id',
'name',
'popularity',
'users_popularity',
'url',
'image',
'genres',
'status',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'id' => 'integer',
'status' => 'boolean',
];
public function setImageAttribute($value)
{
$attribute_name = "image";
// or use your own disk, defined in config/filesystems.php
$disk = config('backpack.base.root_disk_name');
// destination path relative to the disk above
$destination_path = "public/storage/artists";
// if the image was erased
if ($value==null) {
// delete the image from disk
\Storage::disk($disk)->delete($this->{$attribute_name});
// set null in the database column
$this->attributes[$attribute_name] = null;
}
// if a base64 was sent, store it in the db
if (Str::startsWith($value, 'data:image'))
{
$image = \Image::make($value)->encode('jpg', 90);
$filename = md5($value.time()).'.jpg';
\Storage::disk($disk)->put($destination_path.'/'.$filename, $image->stream());
\Storage::disk($disk)->delete($this->{$attribute_name});
$public_destination_path = Str::replaceFirst('public/', '', $destination_path);
$this->attributes[$attribute_name] = $public_destination_path.'/'.$filename;
}
}
public function spotifyUsers()
{
return $this->belongsToMany(\App\Models\SpotifyUser::class);
}
}
I fixed it, I had to add an else statement after
if (Str::startsWith($value, 'data:image'))
in the model where I set $this->attributes[$attribute_name] = $value;.

Rest API : #1062 - duplicate entry for key 'primary'

I want upload some image to server with rest API using Codeigniter.
But I have a problem after upload image / refresh phpmyadmin on this table.
I know this problem is classic, what I'm already todo:
Re-Create the table 2 times.
Make ID to Autoincrement (actually I'm make it AI at first make table)
Not include ID on insert operation, and make it AI automatic.
I'm already truncate the table 2 times
but nothing change anything, at I'm refresh page phpmyadmin this error always appear.
What's my mistake ?
Thanks
If you think my error because my code Rest-API, here's my code:
Controller:
public function upload_post()
{
// $config['max_size'] = '100';
// $config['max_width'] = '1024';
// $config['max_height'] = '768';
$msgCreated = ['status' => true, 'message' => 'Image Has Been Upload'];
$msgFailCreated = ['status' => false, 'message' => 'Failed to Upload Image !'];
$config['upload_path'] = './image/';
$config['allowed_types'] = 'gif|jpg|png';
$this->load->library('upload', $config);
$this->upload->initialize($config);
if (!$this->upload->do_upload('file')) {
$this->set_response($msgFailCreated, 404);
} else {
$info = $this->upload->data();
$image_path = base_url("image/" . $info['raw_name'] . $info['file_ext']);
$data = [
"name_image" => $this->input->post('name_image'),
"image" => $image_path
];
if ($this->mahasiswa->insertImage($data)) {
$this->set_response($msgCreated, 201);
} else {
$this->set_response($msgFailCreated, 400);
}
}
}
Model:
//? Membuat Upload Image
public function insertImage($data){
return $this->db->insert('image', $data);
}

CodeIgniter Suddenly Cannot Upload Image and says Cannot Be Null

Greeting everyone and especially to Senior of CodeIgniter Developer.
I have a problem with website that was built from CodeIgniter (I am not the developer inherited by previous epmployer). This website cannot working properly, especially when upload the image and shows warning about
Error Number: 1048 Column 'article_image' cannot be null
I did try with find the problem on the script and database, but nothing change and because no one change the codes & contents. Today, i try again with changing the "Null into yes" (previously is "No"), and tried to upload the article. It is miracle that it is working but the next problem is the image is gone (broken). I search at other and looking people with same problem with me says that i need to upgrade the CodeIgniter. Mine is 3.0.0 while the latest is 3.1.10. I copy paste the content inside /System and /views/error/cli not making better but make it worse, the image at the web page is gone(missing).
This is my Article_model
defined('BASEPATH') OR exit('No direct script access allowed');
class Article_model extends CI_Model {
public function get_all()
{
// $this->db->order_by('article_date', 'desc');
// $this->db->order_by('article_view', 'desc');
// $query = $this->db->get_where('article', array('flag !=' => 3));
// return $query->result_array();
$query = $this->db->query("SELECT A.*,B.*, A.id AS id_article FROM article AS A JOIN category B ON A.article_category = B.id WHERE A.flag != 3 ORDER BY article_date DESC, article_view DESC ");
return $query->result_array();
}
public function check($article_id)
{
$query = $this->db->get_where('article', array('flag !=' => 3, 'id' => $article_id));
return $query->row_array();
}
public function get_category()
{
$query = $this->db->order_by('category_name', 'ASC')->get_where('category', array('flag' => 1));
return $query->result_array();
}
public function get_tag()
{
$query = $this->db->order_by('tag_name', 'ASC')->get_where('tag', array('flag' => 1));
return $query->result_array();
}
public function get_selected_tag($article_id)
{
$query = $this->db
->select('tag.id, tag_name')
->join('article_tag', 'tag_id = tag.id')
->where(array('tag.flag' => 1, 'article_id' => $article_id))
->get('tag');
return $query->result_array();
}
public function insert()
{
$this->load->helper('upload');
$this->load->library('image_moo');
$image = file_upload('article_image', 'upload/article');
$this->image_moo->load($image['full_path']);
$this->image_moo->resize(924, 527)->save($image['path'] . '/' . $image['file_name'], TRUE);
$this->image_moo->resize_crop(100, 69)->save($image['path'] . '/thumb/' . $image['file_name']);
$this->image_moo->resize_crop(367, 232)->save($image['path'] . '/cover/' . $image['file_name']);
$insert_data = array(
'article_author' => $this->session->admin_id,
'article_title' => $this->input->post('article_title'),
'article_slug' => url_title($this->input->post('article_title'), '-', TRUE),
'article_category' => $this->input->post('article_category'),
'article_image' => $image['file_name'],
'article_content' => $this->input->post('article_content'),
'is_popup' => $this->input->post('is_poup'),
'article_date' => $this->input->post('article_date'),
);
$this->db->insert('article', $insert_data);
$article_id = $this->db->insert_id();
foreach ($this->input->post('article_tag') as $tag)
{
// Check apakah tag itu udah ada di database?
if (is_numeric($tag))
{
$tag_id = $tag;
}
else
{
$this->db->insert('tag', array('tag_name' => strtolower(trim($tag)), 'tag_slug' => url_title(trim($tag), '-', TRUE)));
$tag_id = $this->db->insert_id();
}
if ( ! $this->db->get_where('article_tag', array('article_id' => $article_id, 'tag_id' => $tag_id))->row_array())
{
$this->db->insert('article_tag', array('article_id' => $article_id, 'tag_id' => $tag_id));
}
}
}
public function update($id)
{
$this->load->helper('upload');
$this->load->library('image_moo');
$image = file_upload('article_image', 'upload/article');
$this->image_moo->load($image['full_path']);
$this->image_moo->resize(924, 527)->save($image['path'] . '/' . $image['file_name'], TRUE);
$this->image_moo->resize_crop(100, 69)->save($image['path'] . '/thumb/' . $image['file_name']);
$this->image_moo->resize_crop(367, 232)->save($image['path'] . '/cover/' . $image['file_name']);
$insert_data = array(
'article_author' => $this->session->admin_id,
'article_title' => $this->input->post('article_title'),
'article_slug' => url_title($this->input->post('article_title'), '-', TRUE),
'article_category' => $this->input->post('article_category'),
'is_popup' => $this->input->post('is_popup'),
'article_content' => $this->input->post('article_content'),
'article_date' => $this->input->post('article_date'),
);
if ($image)
{
$insert_data['article_image'] = $image['file_name'];
}
$article_id = $id;
$this->db->where('id', $id);
$this->db->update('article', $insert_data);
$this->db->where('article_id', $id);
$this->db->delete('article_tag');
foreach ($this->input->post('article_tag') as $tag)
{
// Check apakah tag itu udah ada di database?
if (is_numeric($tag))
{
$tag_id = $tag;
}
else
{
$this->db->insert('tag', array('tag_name' => strtolower(trim($tag)), 'tag_slug' => url_title(trim($tag), '-', TRUE)));
$tag_id = $this->db->insert_id();
}
if ( ! $this->db->get_where('article_tag', array('article_id' => $article_id, 'tag_id' => $tag_id))->row_array())
{
$this->db->insert('article_tag', array('article_id' => $article_id, 'tag_id' => $tag_id));
}
}
}
}
What should i do guys? i did backup but it remain same like after upgraded. Thank you. Web Url (http://www.hidupseimbangku.com/)
First. If you want to upgrade CI Version you must follow Upgrading Guide one by one. There may be break changes and you need to correct them, you can find this guide here:
https://www.codeigniter.com/userguide3/installation/upgrading.html
I suggest you rollback upgrade changes and start again doing one by one. It is not hard, it is just time consuming.
The error you're getting is probably related to an error of uploading process. What is file_upload?
I also suggest you read this, for properly file upload.

How to disable unavailable dates in the CJuiDatePicker widget

I am building a scheduling app. I am able to sort the database using the CJuiDatePicker widget's "onSelect" option. Now I am trying to use the "beforeShow" option to ensure that only dates that have tasks can be selectable. Can anyone help?
$this->widget('zii.widgets.jui.CJuiDatePicker', array(
'model'=>$dataProvider,
'attribute'=>'start_time',
'options'=>array(
'dateFormat' => 'yy-mm-dd',
'changeMonth' => true,
'changeYear' => true,
'beforeShowDay' => 'js:$.datepicker.noWeekends',
'beforeShow' => "js:function Check_Alert2(){
Check_Alert();
}
",
'onSelect' => "js:function SearchFunc() {
var data = $('input').serialize();
var url = document.URL;
var params = $.param(data);
url = url.substr(0, url.indexOf('?'));
window.History.pushState(null, document.title,$.param.querystring(url, data));
}"
),
'htmlOptions'=>array(
'style'=>'height:20px;',
'readonly' =>true,
),
));
i am still using the original code. I need an array generated within the beforeshowday. When i run your code it fails on the getdates() function call.
'beforeShowDay' => 'js:function(date){
var array = ["2013-10-30","2013-10-31","2013-12-18","2013-12-25"];
var string = jQuery.datepicker.formatDate("yy-mm-dd", date);
if (array.indexOf(string) == -1){
return [false,"", "No event"];
} else return [true,"", "Event"];

Zend_Form not displaying error message with calling addError

I am implementing an updatePasswordAction and its not displaying an error with an invalid current password. I could not implement this with a Zend_Validate class to use with a supplied record->password, so i just validated for now in my controller action and if failed then i add the error message to the form element. this is just before i run $form->isValid. In any case, its working. but when the validation fails, its not displaying the error message on this on the element. any help would be greatly appreciated.
FYI: When I submit a blank current password, it shows the validation
class Admin_Form_UserPassword extends Katana_Form
{
public function init()
{
$element = $this->createElement('hidden', 'id');
$this->addElement($element);
$element = $this->createElement('password','password');
$element->setLabel('Current Password:');
$element->setRequired(true);
$this->addElement($element);
$element = $this->createElement('password','new_password');
$element->setLabel('New Password:');
$element->addValidator('StringLength', false, array(6,24));
$element->setRequired(true);
$element->addValidator('NotEmpty');
$this->addElement($element);
$element = $this->createElement('password','new_password_confirm');
$element->setLabel('Confirm:');
$element->addValidator('StringLength', false, array(6,24));
$element->addValidator('IdenticalField', false, array('new_password', 'Confirm Password'));
$element->setRequired(true);
$this->addElement($element);
$this->addElement('submit', 'submit', array('label' => 'Submit'));
}
}
public function updatePasswordAction()
{
$resourceModel = new Core_Model_Resource_User();
$form = new Admin_Form_UserPassword();
$form->setMethod(Katana_Form::METHOD_POST);
$form->setAction($this->getActionUrl('update-password'));
if($this->getRequest()->isPost()){
$id = $this->getRequest()->getParam('id');
$record = $resourceModel->find($id)->current();
$currPassword = $record->password;
$typedPassword = md5($this->getRequest()->getParam('password'));
if($currPassword !== $typedPassword){
$form->getElement('password')->addError('Current password is incorrect.');
}
if($form->isValid($_POST)){
$data = $form->getValues();
$result = $resourceModel->updatePassword($id, $data['new_password']);
if($result){
$this->redirectSimple('list');
}
}
} else {
$id = $this->getRequest()->getParam('id');
$recordData = array(
'id' => $id
);
$form->populate($recordData);
}
$this->getView()->form = $form;
}
Adding an error to the element doesn't cause the form itself to then be invalid.
There are at least 2 methods I use to get around this:
if($currPassword !== $typedPassword){
$form->getElement('password')->addError('Current password is incorrect.');
$form->markAsError();
}
// or
if ($form->isValid($_POST) && 0 == sizeof($form->getMessages()) {
// form was valid, and no errors were set on elements
}
To clarify, when you add the error to the form ELEMENT, there is an error attached to that element, but Zend_Form::isValid only runs the validators and sets appropriate errors, it doesn't check to see if you had set an error on a particular element.
You can however call $form->getMessages() to get all the error messages attached to the form or its child elements. If this is 0 and you have validated your form, then it means there were no errors. If your form passed isValid but you added an error to an element, it will include the error message you added.
I made it work this way.
Controller:
if ($trial->getKind() != 'debt' && $_POST['kind'] == 'debt')
{
$editForm->getElement('kind')->markAsError();
}
if ($editForm->isValid($_POST)) { ... }
Form:
public function isValid($data)
{
$valid = parent::isValid($data);
if ($this->getElement('kind')->hasErrors()) {
$this->getElement('kind')->addError($this->_translate->translate('You can\'t change trial kind to debt.'));
$valid = false;
}
return $valid;
}
And this comment helped me.