I have a problem that i can`t get throught.
I am trying to display information from relational table like this:
$dataProvider = PartnerSite::model()->with('siteCommercials')->findAll("user_id=" . Yii::app()->user->id);
$this->render('index', array(
'dataProvider' => $dataProvider,
'allMoney' => 1
));
But in my view i am seeing that error:
Relation "siteCommercials" is not defined in active record class "PartnerSite".
But the fact is that my model have relation:
public function relations() {
return array(
'goesFromSites' => array(self::HAS_MANY, 'GoesFromSite', 'site_id'),
'user' => array(self::BELONGS_TO, 'User', 'user_id'),
'siteCommercials' => array(self::HAS_MANY, 'SiteCommercial', 'site_id'),
);
}
So my question is. Is there is something wrong? I can't get it... In only one that model is a lot of problems... BeforeSave() doesn't work and relations work not well. User relation is working just fine.
Full listing of "model":
<?php
abstract class BasePartnerSite extends GxActiveRecord {
public $siteCommercials = "oke";
public static function model($className=__CLASS__) {
return parent::model($className);
}
public function tableName() {
return '{{partner_site}}';
}
public static function label($n = 1) {
return Yii::t('app', 'PartnerSite|PartnerSites', $n);
}
public static function representingColumn() {
return 'site_name';
}
public function rules() {
return array(
array('site_name', 'required'),
array('user_id', 'numerical', 'integerOnly'=>true),
array('site_name', 'length', 'max'=>255),
array('id, site_name, user_id', 'safe', 'on'=>'search'),
);
}
public function relations() {
return array(
'goesFromSites' => array(self::HAS_MANY, 'GoesFromSite', 'site_id'),
'user' => array(self::BELONGS_TO, 'User', 'user_id'),
'siteCommercials' => array(self::HAS_MANY, 'SiteCommercial', 'site_id'),
);
}
public function pivotModels() {
return array(
);
}
public function attributeLabels() {
return array(
'id' => Yii::t('app', 'ID'),
'site_name' => Yii::t('app', 'Site Name'),
'user_id' => null,
'goesFromSites' => null,
'user' => null,
'siteCommercials' => null,
);
}
public function search() {
$criteria = new CDbCriteria;
$criteria->compare('id', $this->id);
$criteria->compare('site_name', $this->site_name, true);
$criteria->compare('user_id', $this->user_id);
return new CActiveDataProvider($this, array(
'criteria' => $criteria,
));
}
}
Your class is BasePartnerSite. In this class you define relation siteCommercials.
Your error message: "Relation "siteCommercials" is not defined in active record class "PartnerSite".
So then shouldn't your code be?
$dataProvider = BasePartnerSite::model()->with('siteCommercials')->findAll("user_id=" . Yii::app()->user->id);
Related
I am having a yii2 error : common\models\Book has no relation named "favorite".
When I try to add:
public function search($params) {
$query = Book::find();
$query->joinWith(['author', 'profile', 'favorite']);
In the book model I do have the public function:
public function getFavoritedIcon() {
if (isset($this->favorite)) {
return '<i class="glyphicon glyphicon-asterisk books-form"></i>';
} else {
return '';
}
}
And also this extra function to get the icon
public function getFavoritedIcon() {
if (isset($this->favorite)) {
return $icon;
} else {
return '';
}
}
And this works fine in the grid where I want to add sorting and filter:
[
'label' => 'Favorites',
'attribute' => 'favorite',
'value' => 'favoritedIcon',
'hAlign' => 'center',
'vAlign' => 'middle',
'format' => 'raw',
'width' => '50px',
],
I do some different things from another models I am using:
in the grid i get the value as an icon from the book model but i used this before.
the other thing is that the Favorite model has not the same name that the table but it work fine in the grid
abstract class Favorite extends \yii\db\ActiveRecord
{
public static function tableName()
{
return 'user_favorite';
}
/**
* #inheritdoc
*/
public function rules()
{
return [
[['user_id', 'book_id'], 'required'],
[['user_id', 'book_id'], 'integer'],
[['selectedTime'], 'safe']
];
}
Any clues what I am doing wrong ?
======================================================
UPDATE after Pedro del Sol answer
There was some errors in the code but the main one was answered by Pedro, I do had a favorite function in the Book model but not favorites with multiple output.
So now it is working like that:
In the Book model
public function getFavorite() {
$userID = Yii::$app->user->identity->id;
return Favorite::find()->where(['user_id' => $userID, 'book_id' => $this->id])->one();
}
public function getFavorites() {
$userID = Yii::$app->user->identity->id;
return $this->hasMany(Favorite::className(), ['book_id' => 'id'], ['book_id' => $this->id]);
}
public function getFavoritedIcon() {
if (isset($this->favorite)) {
return '<i class="glyphicon glyphicon-asterisk books-form"></i>';
} else {
return '';
}
}
In the BookSearch model:
public function search($params) {
$query = Book::find();
$query->joinWith(['favorites']);
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
$dataProvider->setSort([
'attributes' => [
'title',
'author_id',
'rights_owner_id',
'user_favorite.user_id',
]
]);
and the grid view :
[
'label' => 'Favorites',
'attribute' => 'user_favorite.user_id',
'value' => 'favoritedIcon',
'hAlign' => 'center',
'vAlign' => 'middle',
'format' => 'raw',
'width' => '50px',
],
Having a method to getFavoritedIcon() is not the same as declaring a relation to getFavorite()
I assume that in your Book model class you have the methods getAuthor() and getProfile() which will return queries linking a Book with an Author and a Profile. You'll need something similar with Favorite(s) but I suspect the multiplicities will be different.
I think to declare your relation you'll need something like
/**
* #return \yii\db\ActiveQuery
*/
public function getFavorites()
{
return $this->hasMany(Favorite::className(), ['book_id' => 'ID']);
}
if the relation between Books and Favorites is one to many (most likely) or
/**
* #return \yii\db\ActiveQuery
*/
public function getFavorite()
{
return $this->hasOne(Favorite::className(), ['book_id' => 'ID']);
}
if the relation is one to one.
You can then use joinWith() with either 'favorite' or 'favorites' depending on the multiplicities of your relation.
i want to build a update profile page, and i have 2 mysql table 1. account 2. info, so i want to insert or update the user info table.
this is what i have so far, but its return an error when saving the data "Call to undefined method stdClass::save()"
controller:
public function actionUpdate_profile() {
$model = new UserProfileForm();
$user = Userinfo::model()->findByPk(Yii::app()->user->id);
$model->name = $user->_name;
$model->myurl = $user->myurl;
if (isset($_POST['UserProfileForm'])) {
$model->attributes = $_POST['UserProfileForm'];
if ($model->validate()) {
$model->attributes = $_POST['UserProfileForm'];
$user->name = $model->name;
$user->myurl = $model->myurl;
$user->save();
});
});
$this->render('update_profile', array(
'model' => $model,
'user' => $user,
));
}
model:
class Userinfo extends CActiveRecord {
public static function model($className = __CLASS__) {
return parent::model($className);
}
public function tableName() {
return 'user_info';
}
public function rules() {
return array(
array('email, name, myurl', 'length', 'max' => 255),
);
}
public function attributeLabels() {
return array(
'user_id' => Yii::t('yii', 'Id User'),
'name' => Yii::t('yii', 'First Name'),
'myurl' => Yii::t('yii', 'Last Name'),
);
}
class UserProfileForm extends CFormModel {
public $name;
public $myurl;
public function rules() {
return array(
array('name, myurl', 'required'),
);
}
public function attributeLabels() {
return array(
'name' => Yii::t('yii', 'First Name'),
'myurl' => Yii::t('yii', 'Last Name'),
);
}
}
I know this not best practice but it is concise -
if($user = Userinfo::model()->findByPk(Yii::app()->user->id)) {
//then work with $user here
}
I have three rows in my yii CGridview and having two type of user logins.I have to hide one of the three rows depending on the type of user.Please help.
in your model add public static method
for example:
class Post extends CActiveRecord {
public function tableName() {
return 'posts';
}
public function rules() {
return array();
}
public function attributeLabels() {
return array();
}
...
public static function rulesUser() {
if ( Yii::app()->user->id = 1 ) {
return True;
} else {
return False;
}
}
add in your gridview for row:
$this->widget('zii.widgets.grid.CGridView',
array(
'id' => 'posts-grid',
'dataProvider' => $model->search(),
'filter' => $model,
'emptyText' => '',
'columns' => array(
'id',
'title',
'post',
'date_create',
array(
'name' => 'status',
'visible' => Posts::rulesUser(),
)
array(
'class' => 'CButtonColumn',
),
),
)
);
Use the Conditional statements like this:
public function newsearch()
{
$id= Yii::app()->user->id;
if($id = Your conditon){
$criteria=new CDbCriteria;
$criteria->compare('id',$this->id);
Your Criteria to display
} else {
$criteria=new CDbCriteria;
$criteria->compare('id',$this->id);
Your Criteria to display
}
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
));
}
And Call this dataprovider in your GridView data provider.
or add in model
public $visible = True;
in you search add if or switch
public function search()
{
$criteria = new CDbCriteria;
...
if (any if){
$this->visible = 1;
}
return new CActiveDataProvider($this, array(
'criteria' => $criteria,
));
}
in your gridview
...
array(
'name' => 'value',
'visible'=>$model->visible,
)
...
I have solved the task by conditioning the CDbCriteria as follows,
if(!Yii::app()->session["admin"])
{
$criteria->condition='t.unique_id!="i-8874c6e3"';
}
Thanks all.
So I've inherited a Yii application, I'm trying to get a piece this application to work that does a basic CRUD for management of Scientific factsheets. We're using Yii with Giix
This is the error:
"PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 16 bytes) in /var/www/idtools.org/www/yii/framework/db/ar/CActiveRecord.php on line 58"
The update action is giving us the problems. The update looks like this in the controller:
public function actionUpdate($id) {
$model = $this->loadModel($id, 'Factsheet');
if (isset($_POST['Factsheet'])) {
$model->setAttributes($_POST['Factsheet']);
if ($model->save()) {
$this->redirect(array('view', 'id' => $model->factsheetid));
}
}
$this->render('update', array(
'model' => $model,
));
}
The view looks like:
$this->breadcrumbs = array(
$model->label(2) => array('index'),
GxHtml::valueEx($model) => array('view', 'id' => GxActiveRecord::extractPkValue($model, true)),
Yii::t('app', 'Update'),
);
$this->menu = array(
array('label' => Yii::t('app', 'List') . ' ' . $model->label(2), 'url'=>array('index')),
array('label' => Yii::t('app', 'Create') . ' ' . $model->label(), 'url'=>array('create')),
array('label' => Yii::t('app', 'View') . ' ' . $model->label(), 'url'=>array('view', 'id' => GxActiveRecord::extractPkValue($model, true))),
array('label' => Yii::t('app', 'Manage') . ' ' . $model->label(2), 'url'=>array('admin')),
);
?>
<h1><?php echo Yii::t('app', 'Update') . ' ' . GxHtml::encode($model->label()) . ' ' . GxHtml::encode(GxHtml::valueEx($model)); ?></h1>
<?php
$this->renderPartial('_form', array(
'model' => $model));
?>
The model (as generated by Giix) looks like:
Yii::import('application.models._base.BaseFactsheet');
class Factsheet extends BaseFactsheet
{
public static function model($className=__CLASS__) {
return parent::model($className);
}
}
the model extends the base:
abstract class BaseFactsheet extends GxActiveRecord {
public static function model($className=__CLASS__) {
return parent::model($className);
}
public function tableName() {
return 'factsheet';
}
public static function label($n = 1) {
return Yii::t('app', 'Factsheet|Factsheets', $n);
}
public static function representingColumn() {
return 'name';
}
public function rules() {
return array(
array('name, toolid', 'required'),
array('weight', 'numerical', 'integerOnly'=>true),
array('name, toolid', 'length', 'max'=>255),
array('inputdate', 'safe'),
array('weight, inputdate', 'default', 'setOnEmpty' => true, 'value' => null),
array('factsheetid, name, toolid, weight, inputdate', 'safe', 'on'=>'search'),
);
}
public function relations() {
return array(
'tool' => array(self::BELONGS_TO, 'Tool', 'toolid'),
'factsheetcontents' => array(self::HAS_MANY, 'Factsheetcontent', 'factsheetid'),
'factsheetimages' => array(self::HAS_MANY, 'Factsheetimages', 'factsheetid'),
);
}
public function pivotModels() {
return array(
);
}
public function attributeLabels() {
return array(
'factsheetid' => Yii::t('app', 'Factsheetid'),
'name' => Yii::t('app', 'Name'),
'toolid' => null,
'weight' => Yii::t('app', 'Weight'),
'inputdate' => Yii::t('app', 'Inputdate'),
'tool' => null,
'factsheetcontents' => null,
'factsheetimages' => null,
);
}
public function search() {
$criteria = new CDbCriteria;
$criteria->compare('factsheetid', $this->factsheetid);
$criteria->compare('name', $this->name, true);
$criteria->compare('toolid', $this->toolid);
$criteria->compare('weight', $this->weight);
$criteria->compare('inputdate', $this->inputdate, true);
return new CActiveDataProvider($this, array(
'criteria' => $criteria,
));
}
}
Any idea how to fix my issue? I've given PHP all of my systems memory (memory_init(-1)) and just gotten heap dump errors. I need help, please tell me where to look as I am totally new to Yii.
You generally get that error as part of your _form partial file. I've often run into it when GxHtml is generating a dropdown menu.
GiiX isn't that efficient at properly pulling all the models out of the database and grabbing the appropriate key / name for your drop-downs. So it's often better to specify the fields you want to retrieve manually.
If you post your _form code (or at least the relevant portions), we can point out the line.
So I have schemca very similiar to:
users
--------------
userid, name, password, email
userinroles
--------------
pk, userid, roleid
roles
-----------
roleid, level, description
As you can see the roles table is related to the users via the userinroles table, this is so a user can have edit rights within various groups and have different levels of access for different things. For example they might need to be a page editor while having a super admin rights on a module.
The problem is when I'm updating or creating a record I don't know how to list the roles such that you can check a box to what role they should have and insert that into the userinroles table.
Any ideas on how to do this?
Model:
Yii::import('application.models._base.BaseUser');
class User extends BaseUser
{
public static function model($className=__CLASS__) {
return parent::model($className);
}
public function rules() {
return array(
array('username, password, email', 'required'),
array('isActive, isDeleted, isLocked', 'numerical', 'integerOnly'=>true),
array('username', 'length', 'max'=>50),
// Throws error if user name is not unique
array('username', 'unique', 'attributeName'=> 'username', 'caseSensitive' => 'false'),
array('password', 'length', 'max'=>255),
array('email, organization, position', 'length', 'max'=>100),
array('salt', 'length', 'max'=>32),
array('organization, position, salt, isActive, isDeleted, isLocked', 'default', 'setOnEmpty' => true, 'value' => null),
array('userid, username, password, email, organization, position, salt, isActive, isDeleted, isLocked', 'safe', 'on'=>'search'),
);
}
public function relations() {
return array(
'toolaccesses' => array(self::HAS_MANY, 'Toolaccess', 'userID'),
'usergalleries' => array(self::HAS_MANY, 'Usergallery', 'userid'),
'userinroles' => array(self::HAS_MANY, 'Userinroles', 'userid'),
'tools' =>array(self::MANY_MANY, 'Tool', 'toolid'),
);
}
}
Controller:
class UserController extends GxController {
public function actionView($id) {
$this->render('view', array(
'model' => $this->loadModel($id, 'User'),
));
}
public function actionCreate() {
$model = new User;
if (isset($_POST['User'])) {
$model->setAttributes($_POST['User']);
// salting the user's password before we insert
$model->password = md5(Yii::app()->params["salt"] . $model->password);
if ($model->save()) {
if (Yii::app()->getRequest()->getIsAjaxRequest())
Yii::app()->end();
else
$this->redirect(array('view', 'id' => $model->userid));
}
}
$this->render('create', array( 'model' => $model));
}
public function actionUpdate($id) {
$model = $this->loadModel($id, 'User');
if (isset($_POST['User'])) {
// testing if we need to salt the password.
if(strcmp($_POST['User']['password'], $model->password)!=0)
{ // passwords passed in are not the same. We need to now modify the post password
$_POST['User']['password'] = md5(Yii::app()->params["salt"] . $_POST['User']['password']);
}
$model->setAttributes($_POST['User']);
if ($model->save()) {
$this->redirect(array('view', 'id' => $model->userid));
}
}
$this->render('update', array(
'model' => $model,
));
}
public function actionDelete($id) {
// prevent the deletion of the super user, who has the ID 1.
// This is sort of like a Unix "root" user or a Window's Administrator
if($id == 1)
{
throw new CHttpException(400, Yii::t('app', 'You cannot delete the super admin.'));
}
else
{
if (Yii::app()->getRequest()->getIsPostRequest()) {
$this->loadModel($id, 'User')->delete();
if (!Yii::app()->getRequest()->getIsAjaxRequest())
$this->redirect(array('admin'));
} else
throw new CHttpException(400, Yii::t('app', 'Your request is invalid.'));
}
}
public function actionIndex() {
$dataProvider = new CActiveDataProvider('User');
$this->render('index', array(
'dataProvider' => $dataProvider,
));
}
public function actionAdmin() {
$model = new User('search');
$model->unsetAttributes();
if (isset($_GET['User']))
$model->setAttributes($_GET['User']);
$this->render('admin', array(
'model' => $model,
));
}
}
First, I think you should use Many-Many relation between users and roles table -
public function relations() {
return array(
'toolaccesses' => array(self::HAS_MANY, 'Toolaccess', 'userID'),
'usergalleries' => array(self::HAS_MANY, 'Usergallery', 'userid'),
'roles' => array(self::MANY_MANY, 'Roles', 'userinroles(userid, roleid)'),
'tools' => array(self::MANY_MANY, 'Tool', 'toolid'),
);
After that, you will able to get roles for users with $user->roles. About some actions with roles, related to concrete user: i use this extension to save many-many relations. Sorry if i understood you wrong.