YII file upload not working - php

Hi I am attempting to upload a file and write it to the database using YII, but nothing is happening at all, Its neither saving the file nor name saving to DB.
My View...
<div class="row">
<div class="span4"><?php echo $form->labelEx($model,'slider_image'); ?></div>
<div class="span5"><?php echo $form->fileField($model,'slider_image'); ?></div>
<div class="span3"><?php echo $form->error($model,'slider_image'); ?></div>
</div>
My Model for validation...
public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
//more rules
array('slider_image', 'file', 'types'=>'jpg, gif, png', 'allowEmpty'=>true),
//more rules
);
}
Controller:
public function actionEdit()
{
$id = Yii::app()->getRequest()->getQuery('id');
$model = CustomPage::model()->findByPk($id);
if (!($model instanceof CustomPage))
{
Yii::app()->user->setFlash('error',"Invalid Custom Page");
$this->redirect($this->createUrl("custompage/index"));
}
if(isset($_POST['CustomPage']))
{
$model->attributes = $_POST['CustomPage'];
if (CUploadedFile::getInstance($model,'slider_image')) {
$model->slider_image=CUploadedFile::getInstance($model,'slider_image');
}
if ($model->validate())
{
if ($model->deleteMe)
{
$model->delete();
Yii::app()->user->setFlash('info',"Custom page has been deleted");
$this->redirect($this->createUrl("custompage/index"));
}
else {
$model->request_url = _xls_seo_url($model->title);
if (!$model->save())
Yii::app()->user->setFlash('error',print_r($model->getErrors(),true));
else
{
if (CUploadedFile::getInstance($model,'slider_image')) {
$model->slider_image->saveAs(Yii::app()->baseUrl.'images/'.$model->slider_image);
}
Yii::app()->user->setFlash('success',
Yii::t('admin','Custom page updated on {time}.',array('{time}'=>date("d F, Y h:i:sa"))));
$this->beforeAction('edit'); //In case we renamed one and we want to update menu
}
}
}
}
$this->render('edit',array('model'=>$model));
}
I attempted to die; after if (CUploadedFile::getInstance($model,'slider_image')) and nothing is happening, so it seems its not recognising it at all.
Thank you.

I think you're missing a minor directive in your view
Check to confirm that your form tag has the attribute "enctype"
i.e. <form action="" method="post" enctype="multipart/form-data">...</form>
TO set this in CActiveForm, do:
<?php $form = $this->widget('CActiveForm', array(
'htmlOptions'=>array('enctype'=>'multipart/form-data')
));?>

Related

inserting a value in codeigniter shows no error

I am trying to insert a row to the db using codeigniter.
Model-post.php
class Post extends CI_Model{
function get_posts($num=20, $start=0){
$this->db->select()->from('posts')->where('active',1)->order_by('date_added','desc')->limit($num,$start);
$query=$this->db->get();
return $query->result_array();
}
function get_post($postid){
$this->db->select()->from('posts')->where(array('active' => 1, 'postID'=>$postid))->order_by('date_added','desc');
$query=$this->db->get();
return $query->first_row('array');
}
function insert_post($data){
$this->db->insert('posts',$data);
return $this->db->return_id();
}
Controller-posts.php
class Posts extends CI_Controller{
function __construct(){
parent::__construct();
$this->load->model('post');
}
function index(){
$data['posts'] = $this->post->get_posts();
$this->load->view('post_index', $data);
}
function post($postid){
$data['post']=$this->post->get_post($postid);
$this->load->view('post',$data);
}
function new_post(){
if($_POST){
$data =array(
'title'=>$_POST['title'],
'post'=>$_POST['post'],
'active'=>1
);
$this->post->insert_post($data);
redirect(base_url());
}
else{
$this->load->view('new_post');
}
}
View-new_post.php
<form action="<?php base_url(); ?>posts/new_post" method="action">
<p>Title: <input type="text" name="title"></p>
<p>Description: <input type="textarea" name="post"></p>
<input type="submit" value="Add post">
</form>
Index view-post_index.php
foreach ($posts as $post) { ?>
<div id-="container">
<div><h3><?php echo $post['title']; ?> </h3>
<?php echo $post['post']; ?>
</div>
</div>
<?php
}
The index page shows all the posts from db. On clicking the title it takes to post.php view to show the respective data. This part is fine.
While trying to add a new post in new_post.php it is not reflecting in the db nor showing any error. Also I used redirect_url to redirect to the index page after inserting. So it shows the same available posts. On clicking the title it keeps on adding posts/post to the url repeatedly. Clicking the title once after redirecting the url shows
http://localhost/Codeigniter/posts/posts/post/1
Again on clicking the title it adds
http://localhost/Codeigniter/posts/posts/post/post/1
Can anyone help me? Thanks!
There are numerous issues across the entire application. These are what I found:
Views
Two problems in your new_post view.
You are not echoing out your base_url . You need to replace your form's action attribute.
the method attribute should either have post or get. In this case it should be post
Change it like this:
From this:
<form action="<?php base_url(); ?>posts/new_post" method="action">
To this:
<form action="<?= base_url(); ?>posts/new_post" method="post">
alternatively you can do this:
<form action="<?php echo base_url(); ?>posts/new_post" method="post">
Controller
In your posts controller, your new_post() function should be like this:
function new_post() {
if ($this->input->post()) {
$data = array(
'title' => $this->input->post('title'),
'post' => $this->input->post('post'),
'active' => 1
);
$id = $this->post->insert_post($data);// this is the id return by your model.. dont know what you wann do with it
// maybe some conditionals checking if the $id is valid
redirect(base_url());
} else {
$this->load->view('new_post');
}
}
Model
function insert_post() should not have $this->db->return_id();, instead it should be $this->db->insert_id();
in your model
function insert_post($newpost){
$this->db->insert('posts',$newpost);
// check if the record was added
if ( $this->db->affected_rows() == '1' ) {
// return new id
return $this->db->insert_id();}
else {return FALSE;}
}
any user input must be validated. if you are using Codeigniter then use its form validation and use its input library like:
$this->input->post('title')
an example for blog posts are in the tutorial https://ellislab.com/codeIgniter/user-guide/tutorial/create_news_items.html
otherwise in your controller -- check if the new post id did not come back from the model -- if it did not come back then just go to an error method within the same controller so you don't lose the php error messages.
if ( ! $postid = $this->post->insert_post($newpost); ){
// passing the insert array so it can be examined for errors
$this->showInsertError($newpost) ; }
else {
// success now do something else ;
}

yii validate an input array of phone numbers

I'm working on a multiple contact form in Yii 1.1.16. Where the user can add multiple phone numbers.
Problem is, how would i validate this using Yii's rules()?
<div class="form-group">
<?php
echo $form->labelEx($model,'contacts', array('class'=>'col-md-3 control-label'));
?>
<div class="col-md-9">
<div class="multiple-contact multiple-form-group input-group padding-bottom-10px" data-max="5">
<div class="input-group-btn input-group-select">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
<span class="concept">Phone</span> <i class="fa fa-caret-down"></i>
</button>
<ul class="dropdown-menu" role="menu">
<li>Phone</li>
<li>Fax</li>
<li>Mobile</li>
</ul>
<?php echo $form->textField($model,'contacts',array('type'=>'text', 'class'=>'input-group-select-val', 'name'=>'contacts[type][]','value'=>'phone')); ?>
</div>
<?php echo $form->textField($model,'contacts',array('size'=>60,'maxlength'=>255, 'name'=>'contacts[value][]','class'=>'form-control')); ?>
<?php echo $form->error($model,'contacts'); ?>
<span class="input-group-btn">
<button type="button" class="btn btn-success btn-add"><i class="fa fa-plus"></i></button>
</span>
</div>
</div>
</div>
i tried using this, but doesn't work
public function rules()
{
return array(
array('contacts[value][]', 'required'),
array('contacts[value][]', 'integerOnly'=>true),
array('contacts[value][]','type','type'=>'array','allowEmpty'=>false)
);
}
Here is a sample Fiddle on how the jQuery side works. I want it to be able to validate with 'enableAjaxValidation'=>true,. Also, when more fields are added, it duplicates the id of the input. and no ajax post is done onblur/onfocus
Use custom validation.
Declare a custom validator in your rules, and define the validation you require in the validator method.
public function rules()
{
return array(
array('contacts', validateContacts),
);
}
public function validateContacts($attribute,$params)
{
if (length($this->contacts) == 0) {
$this->addError($attribute, 'You must add at least one contact!');
}
foreach($this->contacts as $contact) {
// ...
}
}
In your controller, assign the contacts array to the Model field and call the model's validation method. If there are any errors it will display through the line
<?php echo $form->error($model,'contacts'); ?>
in the view.
The controller contains the code to invoke the validation.
$contactModel = new Contact;
// assign the array of contacts to the model
$contactModel->contacts = $POST['myForm]['contacts']
$contactsModel->validate();
$this->render('myform', contactModel);
If you want the validation to happen through Ajax, you need to specify so when creating your form:
$form=$this->beginWidget('CActiveForm', array(
'id'=>'top-websites-cr-form',
'enableAjaxValidation'=>true,
'clientOptions' => array(
'validateOnSubmit'=>true,
'validateOnChange'=>true),
));
In this case your controller can check for ajax forms.
if(isset($_POST['ajax']) && $_POST['ajax']==='branch-form')
{
echo CActiveForm::validate($model);
Yii::app()->end();
}
references:
http://www.yiiframework.com/wiki/168/create-your-own-validation-rule/
You should make it a separate model with it's own validation.
Then in your controller you have to validate the main models and the related models separately.
Here is a good guide for such a setup:
http://www.yiiframework.com/wiki/384/creating-and-updating-model-and-its-related-models-in-one-form-inc-image/
To my opinion for best validation regarding phonenumbers you should use libphonenumber php library and there is an extension for it regarding yii framework here http://www.yiiframework.com/extension/libphonenumber/
basic usage:
Yii::setPathOfAlias('libphonenumber',Yii::getPathOfAlias('application.vendors.libphonenumber'));
$phonenumber=new libphonenumber\LibPhone($your_phone_number);
$phonenumber->validate();
for more details regarding usage and capabilities of libphonenumber php library you can find here:
https://github.com/davideme/libphonenumber-for-PHP
Let us consider you have a model called ContactNo and it looks like
class ContactNo extends CFormModel
{
public $contact;
public function rules()
{
return array(
// your rules
array('contact', 'required'),
array('contact','length','min'=>2)
);
}
/**
* Declares attribute labels.
*/
public function attributeLabels()
{
return array(
'contact'=>'Contact No',
);
}
}
The controller as SiteController and the action Name as actionIndex
Then your controller should look something like this
public function actionIndex()
{
// set how many contact fields you want here
$contactCount = 3;
$models = array();
if(isset($_POST['ContactNo']))
{
$successModels = 0;
foreach($_POST['ContactNo'] as $key=>$value)
{
$model = new ContactNo;
$model->attributes = $value;
if($model->validate()) // this validates your model
$successModels++; // it tells how many contact No.s have been validated
$models[$key]=$model;
}
// if all the contact nos are validated, then perform your task here
if($successModels === $contactCount)
{
// save your models
echo 'models saved';
Yii::app()->end();
}
}
else
{
for($index = 0;$index < $contactCount; $index++)
$models[] = new ContactNo;
}
$params = array();
$params['contactCount']=$contactCount;
$params['models']= $models;
$this->render('index',$params);
}
Now lets Go to view. Obviously the view is index.php and it will be something like
// Include all the initial part required for activeforms
<?php echo $form->errorSummary($models); ?>
<?php foreach ($models as $index=>$model): ?>
<div class="row">
<?php echo $form->labelEx($model,"[{$index}]contact"); ?>
<?php echo $form->textField($model,"[{$index}]contact",array('size'=>60,'maxlength'=>128)); ?>
<?php echo $form->error($model,"[{$index}]contact"); ?>
</div>
<?php endforeach; ?>
// Include the submit button
Hope this helps you or might give you an idea atleast to achieve your goal.

YII file upload not adding to database using form

Im attempting to add a file upload field to a form in YII, while its succesfully submitting and uploading the file to the correct folder, its not adding anything to the database.
Im only learning this platform so any guidance would be great.
Here is my view...
<div class="row">
<div class="span4"><?php echo $form->labelEx($model,'slider_image'); ?></div>
<div class="span5"><?php echo $form->fileField($model,'slider_image'); ?></div>
<div class="span3"><?php echo $form->error($model,'slider_image'); ?></div>
</div>
Here is my controller...
public function actionEdit() {
$id = Yii::app()->getRequest()->getQuery('id');
$model = CustomPage::model()->findByPk($id);
if (!($model instanceof CustomPage)) {
Yii::app()->user->setFlash('error',"Invalid Custom Page");
$this->redirect($this->createUrl("custompage/index"));
}
if(isset($_POST['CustomPage'])) {
$model->attributes = $_POST['CustomPage'];
$model->image=CUploadedFile::getInstance($model,'slider_image');
if ($model->validate()) {
if ($model->deleteMe) {
$model->delete();
Yii::app()->user->setFlash('info',"Custom page has been deleted");
$this->redirect($this->createUrl("custompage/index"));
} else {
$model->request_url = _xls_seo_url($model->title);
if (!$model->save()) {
Yii::app()->user->setFlash('error',print_r($model->getErrors(),true));
} else {
$model->image->saveAs(Yii::app()->baseUrl.'images/'.$model->image);
Yii::app()->user->setFlash('success',
Yii::t('admin','Custom page updated on {time}.',array('{time}'=>date("d F, Y h:i:sa"))));
$this->beforeAction('edit'); //In case we renamed one and we want to update menu
}
}
}
}
}
and my model
public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
// other rules
array('slider_image', 'file', 'types'=>'jpg, gif, png'),
);
}
The form itself overall is working fine, unfortunately I dont understand how YII adds to the database
Thanks
Adrian
EDIT: Ive also obviously got a slider_image field in that table
What your Controller code would do is save the file name of the upoloaded file in your database table. Another thing is: your code:
$model->image=CUploadedFile::getInstance($model,'slider_image');
is referring to the wrong attribute. I think it should be:
$model->slider_image=CUploadedFile::getInstance($model,'slider_image');
Finally, you need to call $model->slider_image->save('path.to.file'); in order to save the file to disk
I believe you get stock at $model->validate(). Because you do copy image above this line copying is fine but you do not go through validation so it never saves to DB.
var_dump($model->validate()); to see what is going on...

Yii Captcha not Changing

My Captcha is not changing, always appear the same word, unless clicking on Reload Captcha button. Why testLimit is not working properly?
Controller.php
public $attempts = 5; // allowed 5 attempts
public $counter;
public function actions()
{
return array(
'captcha'=>array(
'class'=>'CCaptchaAction',
'backColor'=>0xf5f5f5,
'testLimit'=>1,
);
}
private function captchaRequired()
{
return Yii::app()->session->itemAt('captchaRequired') >= $this->attempts;
}
public function actionLogin()
{
if (!Yii::app()->user->isGuest) $this->redirect(array('users/update'));
$model = $this->captchaRequired()? new LoginForm('captchaRequired') : new LoginForm;
// collect user input data
if(isset($_POST['LoginForm']))
{
$model->attributes=$_POST['LoginForm'];
// validate user input and redirect to the previous page if valid
if($model->validate() && $model->login()) {
$this->redirect(array('users/update'));
} else {
$this->counter = Yii::app()->session->itemAt('captchaRequired') + 1;
Yii::app()->session->add('captchaRequired',$this->counter);
}
}
// display the login form
$this->render('login',array('model'=>$model));
}
View.php
<?php if($model->scenario == 'captchaRequired'): ?>
<br>
<legend><?php echo CHtml::activeLabelEx($model,'verifyCode'); ?></legend>
<div class="control-group">
<div class="controls">
<?php $this->widget('CCaptcha'); ?>
<?php echo CHtml::activeTextField($model,'verifyCode'); ?>
</div>
</div>
<?php endif; ?>
testLimit is the amount of captcha submission, that user can try before generated hash will be changed. Used for avoid typo mistakes.
Verify code stores in session (http://www.yiiframework.com/doc/api/1.1/CCaptchaAction#getVerifyCode-detail), thus be default code can be changed only one of two ways: submit form with testLimit times with incorrect code, or manual update by user.
So you can extends CCaptchaAction class to achieve what you want, f.g. force set $regenerate variable to true.
Is simple solution, use JScript. This script will be reload image captha.
$(document).ready(function () {
setTimeout(function () {
$("img#reviews-verifycode-image").click();
}, 100);
});

Yii Framework: Undefined variable model when checking if guest

We have a actionSearchType in our User Controller as follows:
public function actionSearchType()
{
if (Yii::app()->user->isGuest == true)
$this->render('login');
else
$this->render('search_type');
}
Our actionLogin in our User Controller is as follows:
public function actionLogin()
{
$model= new Users();
// if it is ajax validation request
if(isset($_POST['ajax']))
{
echo CActiveForm::validate($model);
Yii::app()->end();
}
$this->redirect(Yii::app()->user->returnUrl);
}
}
// display the login form
$this->render('login',array('model'=>$model));
}
The goal is to ensure that only authenticated users can execute the options on the search type view. When I run this page, I receive an error stating Undefined variable: model.
A snippet of the login view is as follows:
<div class="form">
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'login-form',
'enableClientValidation'=>true,
'clientOptions'=>array(
'validateOnSubmit'=>true,
),
)); ?>
<p class="note">Fields with <span class="required">*</span> are required.</p>
<div class="row">
<?php echo $form->labelEx($model,'username'); ?>
<?php echo $form->textField($model,'username'); ?>
<?php echo $form->error($model,'username'); ?>
</div>
What steps must be taken to remedy the above error and properly check to ensure we have an authenticated user?
update
I changed actionSearchType to render the Login Widget per below:
public function actionSearchType()
{
if (Yii::app()->user->isGuest)
$this->widget('ext.LoginWidget');
else
$this->render('search_type');
}
This indeed resolved the error initially seen. A new problem is that there's no styling of the login widget when it renders. Should I echo my tags with appropriate stylesheet classes, or is there a bit more elegant way of doing that?
public function actionSearchType() {
if (Yii::app()->user->isGuest)
$this->redirect('/user/login');
$this->render('search_type');
}
Notes:
to do something when user is guest, simply use if(Yii::app()->user->isGuest) { statement }
to do something when user is logged in, simply use if(!Yii::app()->user->isGuest) { statement }
in the second code, public function actionLogin(), I think you have 2 more closing curly brackets than needed. Anyway, the login action should look like this:
public function actionLogin() {
$formModel = new Login_Form; // Login_Form.php should be in models folder
if (isset($_POST['Login_Form'])) {
$formModel->attributes = $_POST['Login_Form'];
if ($formModel->validate() && $formModel->login()) {
$this->redirect('/'); // replace / with stuff like Yii::app()->user->returnUrl
}
}
$this->render('login', array(
'formModel'=>$formModel,
));
}
Instead of rendering the view redirect to the user login page / action so you don't have to recreate it.
$this->redirect('login');
Somewhere in search_type you are referencing the variable $model which you do not hand over to the render() function. You need to define that variable otherwise the view will create an Exception.
I don't know which Model/Class your search_type view is expecting but you will need to initialize it before you hand it over to the view like this:
$this->render('search_type',array(
'model' => $model,
));
Here a good read about this topic: Understanding the view rendering flow

Categories