I am trying to create dynamic attributes, properties and rules in model class from one table values as columns.
Consider i have one table named "XXX" which has column "Name" now i want to create model class with rules,properties and attributes using the Name values stored in DB.
I am new to YII Framework Can anybody give idea to this ?
This is something i mocked up quickly, I hope it points ou in the right direction
$sql="SELECT 'Name' FROM XXX";
$names =$connection->createCommand($sql)->query()->readAll();
$myDynamicObject = new DynamicModel($names);
class DynamicModel extends CModel
{
protected $_members = array();
public function __construct($nameFields)
{
foreach ($nameFields as $member) {
$this->_members[$member] = null;
}
parent::__construct();
}
/**
* #return array validation rules for model attributes.
*/
public function rules()
{
$allMembers = implode(', ', array_keys($this->_members));
return array(
array($allMembers, 'required'),
);
}
public function __get($attribute)
{
if (in_array($attribute, array_keys($this->_members))) {
return $this->_members[$attribute];
} else {
return parent::__get($attribute);
}
}
public function __set($attribute, $value)
{
if (in_array($attribute, array_keys($this->_members))) {
return $this->_members[$attribute] = $value;
} else {
return parent::__set($attribute, $value);
}
}
public function getAttributes()
{
return $this->_members;
}
public function setAttributes($attributes)
{
$this->_members = $attributes;
}
}
Related
I can't get the value of the foreign key that is inside the booking table.
Booking Table
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class booking extends Model
{
protected $primaryKey = 'bookingID';
protected $fillable = ['clientID', 'checkInDate', 'checkOutDate', 'roomsCount', 'roomTypeID', 'adultsCount', 'childrenCount', 'amenityID', 'paymentID'];
public function client()
{
return $this->hasOne(Client::class,'clientID');
}
}
Client Table
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class client extends Model
{
protected $primaryKey = 'clientID';
protected $fillable = ['fullNmae', 'firstName', 'lastName', 'phoneNumber', 'emailAddress'];
public function booking()
{
return $this->hasMany(Booking::class);
}
}
I tried adding the protected $primaryKey = 'bookingID'; and protected $primaryKey = 'clientID'; as suggested in my previous question but now I still can't get just the FirstName from the client table.
$bookingDetail = booking::with('client')->get();
return $bookingDetail->client->firstName;
You are trying to get a property from a collection in these lines:
$bookingDetail = booking::with('client')->get();
return $bookingDetail->client->firstName;
but this property client is defined for object, not a collection. so to solve it you must take one object from the collection like the following:
$bookingDetail = booking::with('client')->first();
return $bookingDetail->client->firstName;
i thing you need to try this one:
in your booking model:
// 'App\Client' these is example you need to put your client model path
public function client()
{
return $this->belongsTo('App\Client','clientID');
}
in your client model:
public function booking()
{
return $this->hasMany('App\Booking' , 'clientID');
}
I'm a beginner in cakePHP and I'm kind of stuck about retrieving data.
I have a controller, in which I want to get a users deposit amount.
Therefore I have a user model and a deposit model.
The deposit model looks like this:
<?php
App::uses('AppModel', 'Model');
class Deposit extends AppModel {
public $belongsTo = array('User');
public $useTable = 'deposits';
public $validate = array();
public function __construct($id = false, $table = null, $ds = null) {
parent::__construct($id, $table, $ds);
}
public function getDepositAmount() {
// return a users deposit amount
}
}
?>
How can I tell the model to return the amount (database field is called deposit_amount) and how does it know to which user id it belongs to? Thank you!
Uses of belongsTo in CakePhp
class Deposit extends AppModel {
public $useTable = 'deposits';
public $validate = array();
public function __construct($id = false, $table = null, $ds = null) {
parent::__construct($id, $table, $ds);
}
public function getDepositAmount() {
$this->belongsTo('User')
->setForeignKey('user_id');
// your find query here
}
}
Please read doc first for better understanding CakePhp Doc
How can I do this in PHPStorm so hinting works correctly when calling the model() method?
For instance:
/**
* #property-read \Stores $store
*/
class Items extends CActiveRecord
{
public static function model($className = __CLASS__)
{
return parent::model($className);
}
public function relations()
{
return array('store' => array(self::BELONGS_TO, 'Stores', array('store_id' => 'id')),
}
}
$items = new Items;
$items->store; // PHPStorm type hints this correctly
Items::model()->store; // PHPStorm does NOT type hint correctly.
Model above minimalist for focus of this post.
You just have to 'tell' PhpStorm what this method returns.
/**
* #param $className
* #returns Items
*/
public static function model( $className = __CLASS__ ) {
return parent::model( $className );
}
Let's say that I had the following API set up:
Controller:
<?php
namespace app\modules\v1\controllers;
use yii;
class ResourceController extends \yii\rest\ActiveController
{
public $modelClass = 'app\modules\v1\models\Resource';
}
Model:
use yii;
class Resource extends \yii\db\ActiveRecord
{
public static function tableName()
{
return 'ResourceTable';
}
public function fields()
{
return [
'id' => 'ResourceID',
'title' => 'ResourceTitle',
];
}
}
where my table only has the two columns, ResourceID and Title.
When I try a GET request on the API, it works fine and returns the list of resources (or single resource in the case of resource/{id}) with the aliased field names. But when I try to POST to create a resource, I want to use the aliased field names (e.g. title instead of ResourceTitle). The problem is that the default CreateAction supplied by Yii does $model->load(), which looks for the field names in the table. If I use the aliased names then it returns an error. If I use the table field names, it works fine.
So my question is, is there a way to expose resource attributes to the end user where the field names (using the fields() function) are the same for reading and creating? If possible, I'd like to avoid writing my own CreateAction.
It's necessary to add rules for new virtual properties, if you want to $model-load() save parameters to them
class OrganizationBranch extends BaseOrganization{
public function rules()
{
return array_replace_recursive(parent::rules(),
[
[['organizationId', 'cityId'], 'safe'],
]);
}
public function fields() {
return ['id',
'cityId' => 'city_id',
'organizationId' => 'organization_id',
'address',
'phoneNumbers' => 'phone_numbers',
'schedule',
'latitude',
'longitude',
];
}
public function extraFields() {
return ['branchType', 'city'];
}
public function getOrganizationId() {
return $this->organization_id;
}
public function setOrganizationId($val) {
$this->organization_id = $val;
}
public function getCityId() {
return $this->city_id;
}
public function setCityId($val) {
$this->city_id = $val;
}
}
You can create getters/setters for alias.
public function getTitle(){ return $this->ResourceTitle; }
public function setTitle($val){ $this->ResourceTitle = $val ; }
I am trying to call a parent method from its child which has the same method name. Doing so results in a strict standards error. There's an easy solution of renaming the child method. However, is there a way to keep the names of the two methods identical without a standards warning? Thanks.
Strict standards: Declaration of Child::getContentFromDb() should be compatible with Parent::getContentFromDb($id) in /foo/Child.class.php on line xxx
Pseudo-code example:
class Parent {
protected function getInfoFromDb($id) {
return $infoFromDb;
}
}
class Child extends Parent {
public static $id = xx;
public $info = array();
public function __construct() {
$this->info = $this->getInfoFromDb();
}
public function getInfoFromDb() {
// the line below causes the problem
return parent::getInfoFromDb(self::$id);
}
}
Your method override should take the same parameter list as the one you are overriding.
e.g.
class ParentClass {
protected function getInfoFromDb($id) {
return "INFO FROM DB:" . $id;
}
}
class Child extends ParentClass {
public static $id = "xx";
public $info = array();
public function __construct() {
$this->info = $this->getInfoFromDb();
}
/**
* #param specific ID, or do not set for default action.
* #return string
*/
public function getInfoFromDb($id = false) {
return parent::getInfoFromDb(self::$id);
}
}