disable field on rules model yii - yii

i am trying to disable a field on update rules models but i am having error.
i try like:
array('date', 'constraint', 'readOnly'=>true, 'on'=>'update'),
but i am having this error:
"include(constraint.php): failed to open stream: No such file or directory"
I can disable from view using htmloptions but i need do it from model because on update i need to disable more than 5 fields.
how could i do this?
thx in advance

You are declaring a rule with a validator that doesn't exist, so it's normal that you have an error:
array('date', 'constraint', 'readOnly'=>true, 'on'=>'update'),
This line is doing the following: apply the validator constraint on the date field on update scenario with param readOnly set to true.
The validator constraint doesn't exists has a built in functonnality in Yii so if you havn't created it then it doesn't exist!
Documentation:
Validation rules
Model Rules validation
Edit: In your form you could do something like:
<?php
echo $form->textField(
$model,
'email',
array('readonly'=>($model->scenario == 'update')? true : false)
);
?>
As you can see the readonly value will depend on the scenario.

Related

How to pass a parameter to a scenario in Yii?

How to pass $id to search scenario? Maybe in model look like this, so I can call like in controller like:
$model = new job('search',$id);
I think that you are trying to do a search. Search is one thing, a "scenario" is something else.
Scenarios are used in validation rules in order to be able to validate the same model in multiple ways depending from where you're inserting/adding OR searching data.
There's also a scenario called 'search' that is used by the model's search() method, but I tell you why:
There are a couple of ways to search for something in your database using Yii, I will mention two:
1) By using ClassName::model()->findCommandHere
And there are a couple of them:
ClassName::model()->findByPk($id);
ClassName::model()->findAll("id=$id");
ClassName::model()->findByAttributes(array('id'=>$id));
And so on, more here: http://www.yiiframework.com/doc/guide/1.1/en/database.ar#reading-record
2) By using the model's search() method
This way of finding data is mostly used for easily creating search pages and in combination with data grids.
If you generate CRUD code with the GII code generation tool it will generate all the parts for you, but I will explain each part how it works.
This code is from the blog demo found in Yii files:
In controller it defines a $model using Post class and 'search' as scenario.
$model=new Post('search');
if(isset($_GET['Post'])) // <- checks if there are search params in the URL
$model->attributes=$_GET['Post']; // <- assigns all search params masively to the model (later you'll see why)
$this->render('admin',array(
'model'=>$model,
));
The 'search' scenario here tells Yii what validation rules to use when assigning search parameters directly from $_GET (URL).
You can see that the params are assigned massively to reduce code written but $model->attributes=$_GET['Post'] it is the same as doing:
$model->title=$_GET['Post']['title'];
$model->status=$_GET['Post']['status'];
In the Post model you can find the validation rules for the search scenario. Tells Yii that it is safe to assign title and status fields in order to later use them in the search.
public function rules()
{
return array(
// ... //
array('title, status', 'safe', 'on'=>'search'),
);
}
Then also in the Post model you can see the search() method that will actually be used to get the data:
public function search()
{
$criteria=new CDbCriteria;
$criteria->compare('title',$this->title,true);
$criteria->compare('status',$this->status);
return new CActiveDataProvider('Post', array(
'criteria'=>$criteria,
'sort'=>array(
'defaultOrder'=>'status, update_time DESC',
),
));
}
The search method creates a "criteria" and applies the desired way of filtering using the values you have previously assigned to this model. See the $this->title it comes from the $model->attributes=$_GET['Post'] you used in the controller.
The criteria can be used directly on the model, such as Post::model()->findAll($criteria), but in this case the search() method uses something different, a "data provider".
The data provider is a good thing because it provides you a lot of tools in one place, it returns you the data, but also the pagination, and the sorting, so you don't have to manually define more code for that purposes (CPagination, CSort).
Finally, in the view admin.php in this case it will display the results using a grid view:
$this->widget('zii.widgets.grid.CGridView', array(
'dataProvider'=>$model->search(),
'filter'=>$model,
'columns'=>array(
array(
'name'=>'title',
'type'=>'raw',
'value'=>'CHtml::link(CHtml::encode($data->title), $data->url)'
),
array(
'name'=>'status',
'value'=>'Lookup::item("PostStatus",$data->status)',
'filter'=>Lookup::items('PostStatus'),
),
),
));
Now you can see that in the configuration of the grid it passes $model->search() method as the dataProvider that the grid should use.
Now the grid can access the rest of the dataProvider elements such as sort, pagination and display them on the page.
If you did not want to use the CGridView because it's a very basic table and you want to create your own html markup, you can also retrieve the dataProvider and its components one by one and place them in your HTML code and display data as you want:
$dataProvider=$model->search(); // get the dataprovider from search method
$models=$dataProvider->getData(); // actually get the data (rows) and assign them to a $models variable that you can put in a foreach loop
// show pagination somewhere
$this->widget('CLinkPager', array(
'pages' => $dataProvider->pagination,
));
// create sort links
echo $dataProvider->sort->link('title', 'Title');
So I hope it solves some of your doubts on how to use Yii for displaying/searching data.
I suggest you read the official manual: http://www.yiiframework.com/doc/guide/1.1/en/index
I also suggest to look at the API and so search there all the Yii components to see what methods and params they have: http://www.yiiframework.com/doc/api/
Also exploring the framework codebase manually is quite a good way to learn. If you don't know how CActiveDataProvider works, then find the CActiveDataProvider class file in the code and you'll see all the methods and properties that it uses, so do this for everything you don't understand how it works.
Also for beginners I recommend using a good IDE that auto-completes code and allows you to Ctrl+Click a class name and it will locate the original file where it was defined. I use NetBeans for PHP and after creating a project I add Yii framework files to the project's include paths that way NetBeans knows how to find the framework files for auto-complete and for ctrl+click.
Yes you can define scenario with parameter but that is included within the class constructor of the model
$model = new Job('search'); // creating a model with scenario search
If you wish to include more parameters, then you need to use createComponent -remember, all is a component
$model = Yii::createComponent(array('class'=>'Job','scenario'=>'search'));
I think this will simply do the job without needing any scenario
$model = new job;
$model->search($id);
But If I have failed to understand your problem then you can also try this
$model = new job('search');
$model->search($id);
Think of scenarios as a special variable that you can use in the model.
$userModel = new User("register");
$userModel->setId = 10;
which is the same
$userModel = new User();
$userModel->scenario = 10
$userModel->setId = 10;
And in your model
class Manufacturer extends CActiveRecord
{
// :
if ($this->scenario == 'register') ...
// :
}

get model name in yii for jquery

In my CJuiAutoComplete, I currently have the code below.
$this->widget('zii.widgets.jui.CJuiAutoComplete', array(
'name'=>'ABCForm[postcode]',
'id'=>'ABCForm_postcode',
..........
));
Is there a way to get the model name so I don't have to hard code it in my jquery?
In case I change the name in the future, I don't have to go though all my JS code to change the name and id.
I think you should use CHtml::activeId and CHtml::activeName as it fits Yii much better. So your code would look like:
$this->widget('zii.widgets.jui.CJuiAutoComplete', [
'name'=>CHtml::activeName($model, 'postcode'),
'id'=>CHtml::activeId($model, 'postcode'),
//..........
]);
EDIT: I have never used CJuiAutoComplete before but wouldn't it make more sense to use its model and attribute widget parameters (http://www.yiiframework.com/doc/api/1.1/CJuiInputWidget#model-detail):
$this->widget('zii.widgets.jui.CJuiAutoComplete', [
'model'=>$model,
'attribute'=>'postcode',
//..........
]);
If you have passed a model using the variable $model to your view, you can try:
get_class($model)

Lithium link routing

I am trying to create my first Lithium app and I'm getting a very odd error.
I have a line in my index view,
<td><?php echo $this->html->link($question->title, array('controller'=>'questions','action'=>'view','id'=>$question->id)); ?></td>
Which I would imagine would link to that records view, and using 'questions/view'.$question->id' it does, however, using an array url I get a fatal.
Fatal error: Uncaught exception 'lithium\net\http\RoutingException' with message 'No parameter match found for URL('controller' => 'questions', 'action' => 'view', 'id' => '1').' in /Applications/MAMP/htdocs/learning-lithium/libraries/lithium/net/http/Router.php on line 306
Which to me looks like the router is trying to match the url in the helper, and as it can't, for some reason, it's throwing an exception. Does anyone have any idea's why this is? I'm attacking Lithium from a CakePHP standpoint, so this seems odd to me.
The 'args' param is handled by the default routes and get passed in as arguments to your action method.
Try this:
<?=$this->html->link($question->title, array('Questions::view', 'args' => array($question->id))); ?>
To route it with an id param, you need to specify a route that looks for an id param via {:id}. Look in the default routes.php file for the "Database object routes" section. That has some examples which I'll copy below for completeness:
/**
* ### Database object routes
*
* The routes below are used primarily for accessing database objects, where `{:id}` corresponds to
* the primary key of the database object, and can be accessed in the controller as
* `$this->request->id`.
*
* If you're using a relational database, such as MySQL, SQLite or Postgres, where the primary key
* is an integer, uncomment the routes below to enable URLs like `/posts/edit/1138`,
* `/posts/view/1138.json`, etc.
*/
// Router::connect('/{:controller}/{:action}/{:id:\d+}.{:type}', array('id' => null));
// Router::connect('/{:controller}/{:action}/{:id:\d+}');
/**
* If you're using a document-oriented database, such as CouchDB or MongoDB, or another type of
* database which uses 24-character hexidecimal values as primary keys, uncomment the routes below.
*/
// Router::connect('/{:controller}/{:action}/{:id:[0-9a-f]{24}}.{:type}', array('id' => null));
// Router::connect('/{:controller}/{:action}/{:id:[0-9a-f]{24}}');
So you would need to uncomment one of those two sections depending on what format your ids take. They use regular expressions with the id param to make sure it doesn't match url arguments that aren't ids. Incidentally, the first route is setting the default value for id to null which doesn't exactly make sense to me because I don't think the route will ever match with a null value, but anyway, that is how you set default values for your params.
Note that if you do this, your controller action method needs to look like this:
public function view() {
$id = $this->request->id;
// or an alternative that does the same thing
// $id = $this->request->get("params::id");
// ... etc ...
}
The only way to get url pieces passed in as arguments to your controller action method is to use the 'args' param.
You're not using named parameters in your route, so just output the following in your view:
<?php echo $this->html->link($question->title, array('controller'=>'questions', 'action'=>'view', $question->id));?>
Your function signature in QuestionsController should simply be:
public function view($id) {}

Does Yii's Gii's CRUD generator take into account models' relations?

I used Yii's Gii's CRUD generator for a model that has a relation defined with another model, expecting that it would create some sort of dropdown or other way to select an instance of the related entity, but rather it just showed a regular textbox.
Is this the normal behavior of Gii or did I do something wrong?
This are the models and their relations:
Model Event: relation 'Venue' => array( self::BELONGS_TO, 'Venue', 'venue' )
Model Venue: relation 'Events' => array( self::HAS_MANY, 'Event', 'venue' )
I was expecting the Event CRUD to show some way of picking an instance of Venues.
That is just normal behaviour for Gii, when generating forms(for both CRUD and only forms), it makes all input fields textfields. So the default gii CRUD and form generator doesn't take relations into account while generating code.
We have to manually make changes to the view file, namely _form.php for the model in question, for you that is Event.
So for your requirement, you can make the following changes to that file :
/* As you have 'venue' field as the foreign key in the Event model */
<div class="row">
<?php echo $form->labelEx($model, 'venue'); ?>
<?php echo $form->dropDownList($model,'venue', CHtml::listData(Venue::model()->findAll(),
'id', //this is the attribute name(of Venue model- could be the id of the venue) for list option values
'name' // this is the attribute name(of Venue model- could be the name of the venue) for list option texts
)
); ?>
<?php echo $form->error($model,'venue'); ?>
</div>
To make further changes/customizations read more about CActiveForm.
Hope this helps.
Use Giix it works perfactly for what you are looking for.. no manual modifications required.

how to make rules in model using yii framework?

In my application I have 1 field name contact_no,in that i want validation like +91-(999)-(846)-1062
If I'm writing like this
array('contact_no','pattern'=>'/^[0-9-()\s+]+$/'),
then i got error like
invalid validation rule. The rule must specify attributes to be validated and the validator name.
Then what to write in model.
the syntax is not correct,try this:
array('contact_no', 'match', 'pattern'=>'/^[0-9-()\s+]+$/'),
What you need is CRegularExpression with a 'pattern'. The validator name for this is 'match'.