yii, how to use getAttributeLabel() - yii

I have a problem on yii model, ive been told to use the generateAttributeLabel() on the model, but i tried to use it on the way i thought it would work but it doesnt. This is my code
public function generateAttributeLabel($variable = file_get_contents('protected\column.txt'))
{
return $variable;
}
public function attributeLabels()
{
return array(
'id' => 'ID',
'parametro_id' => 'Parametro',
);
}
There are some columns that are being generated automatically and i thought to save their names into a file and its saved as example like (index, par, tolt, sircer). Thats why the file_get_contents(), but i get an error:
Parse error: syntax error, unexpected '(', expecting ')'.
so i really dont know and i need this to make checkboxlist with the attributes of each column thats going to be saved as y or n, if someone could tell me how to use this with checkboxlist would be appretiated.
the content file is this
lololo,
for now it has 1 element, but will be adding more each time a column is created

You can't use a function return value as a default value in a function declaration, you will need to set that up in the function itself
public function generateAttributeLabel($variable = null){
if($variable){
$variable = file_get_contents($variable);
}
return $variable;
}

Related

Laravel 9 accessors and mutators - Simple example not working

So I am trying to get my mutators and accessors to work in Laravel 9, in my Tag model I have the following:
protected function name(): Attribute
{
return Attribute::make(
get: fn ($value) => strtolower($value),
set: fn ($value) => strtolower($value),
);
}
When displaying the name in my blade view however, the name is not being displayed in lower cases ({{ $tag->name }}), also not when saving a new model to the database.
The following does work btw:
public function getNameAttribute($value)
{
return strtolower($value);
}
Also when using public it does not work:
public function name(): Attribute
Just trying to understand what I am doing wrong here?
I am using Laravel version 9.44
I dont know if the question's content is exactly your code. I had a similiar problem, get and set not working. But it worked in other model files.
I just found the solution once again, ya, once again.
If the attribute(column name) has two words, you have to make it together, first word should be lowercase.
short_name
protected function shortName(): Attribute
{
return Attribute::make(
get: fn ($value) => strtolower($value),
set: fn ($value) => strtolower($value),
);
}
Inject the class at top of page like below
use Illuminate\Database\Eloquent\Casts\Attribute;

Laravel Controller/Modal order by in all()

Trying to sort my table. The numbers are category_id and they are not sorted by number (1 and 2 are at the bottom of the table), I want to order them.
Controller:
public function fetchcategory(){
$all_categories = HmsBbrCategory::all();
return response()->json([
'all_categories'=>$all_categories,
]);
}
When I try the code below, I get 500 internal server error in my console:
$all_categories = HmsBbrCategory::orderBy('category_id', 'ASC')->all();
What am I doing wrong witht the orderBy code?
Just for reference to know difference between all() and get()
all()
Its a static method so you cant execute additional queries.Only option you have in all() method is you can select columns.
public static function all($columns = ['*'])
{
return static::query()->get(
is_array($columns) ? $columns : func_get_args()
);
}
If we see implementation of that static all() method. Internally it calls get() method
1.all() accept columns as array. Default set to * ,it means all columns selected.
2.Inside of that method ,we can see get() called. So after get we cant call any query operations so its throwing error
get() is Eloquent builder \Illuminate\Database\Eloquent\Builder
Simply you have to update this line
$all_categories = HmsBbrCategory::orderBy('category_id', 'ASC')->all();
into
$all_categories = HmsBbrCategory::orderBy('category_id', 'ASC')->get();
then you will get your result .

Yii2 REST API relational data return

I've set up Yii2 REST API with custom actions and everything is working just fine. However, what I'm trying to do is return some data from the API which would include database relations set by foreign keys. The relations are there and they are actually working correctly. Here's an example query in one of the controllers:
$result = \app\models\Person::find()->joinWith('fKCountry', true)
->where(..some condition..)->one();
Still in the controller, I can, for example, call something like this:
$result->fKCountry->name
and it would display the appropriate name as the relation is working. So far so good, but as soon as I return the result return $result; which is received from the API clients, the fkCountry is gone and I have no way to access the name mentioned above. The only thing that remains is the value of the foreign key that points to the country table.
I can provide more code and information but I think that's enough to describe the issue. How can I encode the information from the joined data in the return so that the API clients have access to it as well?
Set it up like this
public function actionYourAction() {
return new ActiveDataProvider([
'query' => Person::find()->with('fKCountry'), // and the where() part, etc.
]);
}
Make sure that in your Person model the extraFields function includes fKCountry. If you haven't implemented the extraFields function yet, add it:
public function extraFields() {
return ['fKCountry'];
}
and then when you call the url make sure you add the expand param to tell the action you want to include the fkCountry data. So something like:
/yourcontroller/your-action?expand=fKCountry
I managed to solve the above problem.
Using ActiveDataProvider, I have 3 changes in my code to make it work.
This goes to the controller:
Model::find()
->leftJoin('table_to_join', 'table1.id = table_to_join.table1_id')
->select('table1.*, table_to_join.field_name as field_alias');
In the model, I introduced a new property with the same name as the above alias:
public $field_alias;
Still in the model class, I modified the fields() method:
public function fields()
{
$fields = array_merge(parent::fields(), ['field_alias']);
return $fields;
}
This way my API provides me the data from the joined field.
use with for Eager loading
$result = \app\models\Person::find()->with('fKCountry')
->where(..some condition..)->all();
and then add the attribute 'fkCountry' to fields array
public function fields()
{
$fields= parent::fields();
$fields[]='fkCountry';
return $fields;
}
So $result now will return a json array of person, and each person will have attribute fkCountry:{...}

Yii model is validating but data could not be saved

I have a yii application. Data is validated properly. the $model->validate() returns true but data is not being saved. Is there any way that I know about the error. It does nothing. neither prints error nor any warning.
if (isset($_POST['Invoice'])) {
$model->validate();
$model->attributes = $_POST['Invoice'];
if (!$model->validate()) {
die(CVarDumper::dump($model->errors,10,true));
}
if ($model->save()) {
die("Data saved");
$this->redirect(array('view', 'id' => $model->id));
} else {
CVarDumper::dump($model->attributes,10,true);
CVarDumper::dump($model->errors,10,true);
}
}
if you override beforeSave or afterFind method in your model,
public function beforeSave() {
return true; //don't forget this
}
public function afterFind() {
return true; //don't forget this
}
make sure you return true for those function
If save() is returning true and there are no errors as such in your database and queries. Only thing, thats possible is you haven't marked some of the column safe for mass assignment via "$model->attributes".
Make sure the column you are trying to save are marked safe in the "rules" function in your model. You can mark columns safe via adding the following rule in "rules" function in the model.
array ( "column_name1, column_name2 ....." , "safe" )
I've just ran into something similar to this. Everything was validating correctly, and $model->save() was returning true, but no data was saved in the database.
The problem and solution was that I was creating the $model object like so:
$model = ClassName::model();
but you need to create the object like so:
$model = new ClassName;
If you have this problem, you replace this:
$model->save(false)
This solves your problem.
If you use $model->save(); the filters is running that is not good for you.
Fire up some logging and see what going on...
I got the same error when I was using reCaptcha. I just did this and it worked:
$model->scenario = NULL;
Make sure you do this AFTER validation.
I had the same issue, my mistake was with the post name in the controller, where I used $model->save. I had given wrong - if(isset($_POST['postname']))
If I am not wrong, you are doing an AR save() in the $model->save() method. You do not get any error, but the data is not saved as well.
If this is the case you would like to do a:
die(CVarDumper::dump($arObj->errors,10,true));
after the $arObj->save(); call. Most of the time this happens because of the Database rejecting the values provided for insert or update.
Also do not override your model constructor:
function __construct() { } // don't do this
The issue for me was that I had a property for the column name in the ActiveRecord class, so it wasn't saving.
You should not declare properties for column names as I guess the magic methods __get() and __set() are used to save data, I guess by checking if there are column changes when you click the save() method to avoid useless SQL queries. In my case, because the column was a user-declared property, it wasn't in the columns list and therefore changes to it were not detected.
Hope this helps other people

How to validate >1 field at a time, in a Zend sub-form?

I've created a 3 screen "wizard" using the Zend_Form_SubForm example from the online reference documentation.
The requirement I'm having trouble meeting is this:
If fields 1, 2, & 3 of the first screen are already in the database, notify the user that they are trying to add a duplicate record. Each of those fields has their own validators. Somehow I need to add this "group validator".
So, at its most basic level, I'm trying to do:
if($field_1_not_in_db && $field_2_not_in_db && $field_3_not_in_db){
return true;//validation OK
} else {
return false;//invalid data
}
I am coming up against several issues, though:
1) Because it applies to multiple fields, I don't know which field to attach it to. Error messages appear beside the field they are attached to, so this is important... unless I can get these "multi-field validator" errors to appear at the top of the screen, which would be ideal.
2) My validator is only receiving a single value (the value of the field I attach it to, not the values of the multiple fields it is supposed to validate).
3) I provide a link to the original (non-duplicate) record in the error message, but it escapes the link, and I can't figure out how to get around that.
The setup I'm currently using (below) actually executes fine, but NewPlace validator receives $_POST['city_fk'] as $fields, instead of the desired group of posted values.
$city_fk = new Zend_Form_Element_Select('city_fk');
$cities = array();
$city_fk->setMultiOptions($cities)
->setLabel('City')
->setDescription('The city this place is in')
->setRequired(true);
$v = array(
'place_is_unique' => array(
'NewPlace',
'fields' => array('place_name','phone_number','phone_extension','street','post_code_name'),
)
);
$city_fk->addValidators($v);
$addressSubForm->addElement($city_fk);
class My_Validate_NewPlace extends Zend_Validate_Abstract
{
public function isValid($fields)
{
$result = false;
if(!$result)
{
$this->_error('sorry, this is duplicate data. see it here');
return false;
}
return true;
}
}
This won't help you decide which field to attach the validation to, but...
There is a thing called a "validation context" that helps.
When you create your custom validator or form IF you specify a second optional parameter ($context = null), then Zend will auto-populate this with the entire array of posted data, which you can use to incorporate other fields values into your validation. Here's a very basic example:
$city_name = new Zend_Form_Element_Text('city_name');
$place_name = new Zend_Form_Element_Text('place_name');
$place_name->addValidator('NewPlace');
class My_Validate_NewPlace extends Zend_Validate_Abstract
{
public function isValid($value, **$context = null**)
{
if(trim($value)!='' && trim($context['city_name']) != '')
{
return true;
}
return false;
}
}