Is possible to associate models with current time conditions? - php

Is possible to get two models associated with current time condition?
<?php
class SomeModel extends AppModel {
public $hasOne = array(
'ForumBan',
'ForumBanActive' => array(
'className' => 'ForumBan',
'conditions' => array('ForumBanActive.end_time >' => time()) // fatal error
),
);
}
I don't want to add this condition every time i call find on ForumBan model.

Basic lesson in php OOP: You can't call methods and functions in object property declarations. http://php.net/manual/en/language.oop5.properties.php
Set the association in the __construct() method of the model or use bindModel():
public function __construct($id = false, $table = null, $ds = null) {
parent::__construct($id, $table, $ds);
$this->hasOne['ForumBanActive']['conditions'] = array('ForumBanActive.end_time >' => time()));
}
public $hasOne = Array(
'ForumBan',
'ForumBanActive' => array('className' => 'ForumBan'),
'UserFile',
'BlogProfile',
);

like i said, thanks #burzum for advice, but copy-past solution from my answer isn't cool, shame on you!
Following #burzum answer i got wanted result.
public function __construct($id = false, $table = null, $ds = null) {
parent::__construct($id, $table, $ds);
$this->hasOne['ForumBanActive']['conditions'] = array('ForumBanActive.end_time >' => time()));
}
public $hasOne = Array(
'ForumBan',
'ForumBanActive' => array('className' => 'ForumBan'),
'UserFile',
'BlogProfile',
);

Related

not save data to 2 table have foreigenkey oncakephp

On project cakephp. I have 2 model
<?php class VisaPerson extends AppModel {
public $name = 'VisaPerson';
public $primaryKey = 'id';}?>
and
<?php class VisaProcess extends AppModel {
public $name = 'VisaProcess';
public $primaryKey = 'id';
public $belongsTo = array(
'VisaPerson' => array (
'className' => 'VisaPerson',
'foreignKey' => 'people_id'
)
);
}
?>
In controller, I writed:
if ($this->request->is('post')) {
if (!empty($this->request->data)) {
$person = $this->VisaPerson->save($this->request->data);
if (!empty($person)) {
$this->request->data['VisaProcess']['people_id'] = $this->$person->id;
$this->VisaPerson->VisaProcess->save($this->request->data);
}
}
Data saved on VisaPerson but on VisaProcess people_id not auto save.
Plese help me!
As I remember you need to add this into yours VisaPerson model:
public $hasMany = array(
'VisaProcess' => array(
'className' => 'VisaProcess',
'foreignKey' => 'people_id'
)
);
After that you only need to save VisaPerson and both tables will be filled (if $this->request->data['VisaProcess'] and $this->request->data['VisaPerson'] exists):
$this->VisaPerson->save($this->request->data);

ORM: Change parent's "updated_at" timestamps when model gets updated in FuelPHP

Let's say I have a Model_Post that has_may Model_Comment.
Is there any way that the updated_at field of Model_Post gets updated every time that a new comment is saved? I checked the documentation for the observers, but I cannot find how to do that in a "ORM way".
This code doesn't seem to work:
class Model_Comment extends \Orm\Model
{
protected static $_properties = array(
'id',
'post_id',
'text',
);
protected static $_belongs_to = array('post');
protected static $_observers = array(
'Orm\\Observer_UpdatedAt' => array(
'events' => array('before_save'),
'relations' => array('post')
)
);
}
class Model_Post extends Model
{
protected static $_properties = array(
'id',
'title',
'text',
'updated_at'
);
protected static $_has_many = array('comments');
}
I create a new comment using this code:
$comment = Model_Comment::forge();
$comment->message_id = Input::post('message_id');
$comment->text = Input::post('text');
$comment->save();
Instead of mucking about with observers, seeing as you want an ORM-centric approach, you can fetch the parent, update its updated_at, then commit both objects to the DB via the ORM.
However, you're not implementing the whole observer config:. You're missing the property key, and the mysql_timestamp key.
// Adding it with config:
// - only needs to run on before_save
// - use mysql timestamp (uses UNIX timestamp by default)
// - use just "updated" instead of "updated_at"
protected static $_observers = array(
'Orm\\Observer_UpdatedAt' => array(
'events' => array('before_save'),
'mysql_timestamp' => true,
'property' => 'updated',
'relations' => array(
'my_relation',
),
),
);
FuelPHP Observer_UpdatedAt
If you use the relations property of the observer config you can have the updated_at update when relations change. As long as your child model has a relation to the parent model you can add the relation name into the relations property and the ORM will do the rest for you when you save the model.
Please see the first paragraph under the code sample in the documentation.
Finally I found the way to do that thanks to Uru's comments.
This code works now as I wanted; it was simpler than I thought.
Models:
class Model_Comment extends \Orm\Model
{
protected static $_properties = array(
'id',
'post_id',
'text',
);
protected static $_belongs_to = array('post');
}
class Model_Post extends \Orm\Model
{
protected static $_properties = array(
'id',
'title',
'text',
'updated_at'
);
protected static $_has_many = array('comments');
protected static $_observers = array('Orm\Observer_UpdatedAt');
}
And in the controller:
$comment = Model_Comment::forge();
$comment->text = Input::post('text');
$parent_post = Model_Message::find(Input::post('post_id'));
$parent_post->comments[] = $comment;
$parent_post->save();

CakePHP trouble linking data from 2 tables in models

I am having trouble with linking data like first name from the table Users in the view of chats using cakePHP. Below is my code and whatever I do, the script does not select the user_id from the chats database table to display the first name. I must be overseeing something, but the loop I'm thinking in is giving me some headaches. Can someone please get me out of this loop?
User.php
<?php
class User extends AppModel {
public $hasMany = array(
'Ondutylog',
'Chat'
);
}
?>
Chat.php
<?php
class Chat extends AppModel {
public $belongsTo = array(
'User'
);
}
?>
ChatsController.php
<?php
class ChatsController extends AppController {
var $uses = array('User', 'Chat');
public function view() {
$chats = $this->Chat->find('all', array(
'order' => array('id' => 'ASC'),
'recursive' => -1
));
$this->set('chats', $chats);
$id = $chats['Chat']['user_id'];
$userdetails = $this->Chat->User->find('first', array(
'conditions' => array(
'id' => $id
),
recursive' => -1
));
return $userdetails;
}
}
?>
view.ctp
<?php
foreach($chats as $chat) :
echo "<tr>";
echo "<td>".$userdetails['User']['firstname']."</td>";
echo "<td>".$chat['Chat']['user_id']."</td>";
echo "<td>".$chat['Chat']['text']."</td>";
echo "<td>".$chat['Chat']['created']."</td>";
echo "</tr>";
endforeach
?>
The array I get returned in $chats
[Chat] => Array
(
[id] => 1
[user_id] => 11
[text] => hello
[created] => 2014-05-21 19:56:16
[modified] => 2014-05-21 19:56:16
)
Change
return $userdetails;
to
$this->set(compact('userDetails'));
You are supposed to set the view var not return the info.
Though why are you making a separate query for it instead of just using 'recursive' => 0 which would get the associated user record through table join and you can just use $chat['User']['firstname'] in view.
Also get rid of var $uses = array('User', 'Chat');. It's not needed. $this->Chat is already available and the User model is accessed through association as $this->Chat->User as you have already done.
You need charge the model in your controller
class ChatsController extends AppController {
public function view() {
$this->loadModel('User');
$this->loadModel('Chat');
$chats = $this->Chat->find('all', array(
'order' => array('id' => 'ASC'),
'recursive' => -1
));
$this->set('chats', $chats);
$id = $chats['Chat']['user_id'];
$userdetails = $this->Chat->User->find('first', array(
'conditions' => array(
'id' => $id
),
recursive => -1
));
$this->set(compact('userDetails'));
}
}
I found the solution and it's closer than I thought of myself. Because the Models User and Chat were already joined I just had to use a couple of lines in the Controller. So I modified it like this:
public function view() {
$chats = $this->Chat->find('all');
$this->set('chats', $chats);
}
And nothing more...

FuelPHP - Using Core Classes in ORM Models

How can I use a core classe in my ORM Model ?
Is working:
protected static $_properties = array(
'id',
'user_id',
'v_key' => array('default' => 'abc' ),
'a_key' => array('default' => 'def' ),
'created_at',
'updated_at'
);
Isn't working:
protected static $_properties = array(
'id',
'v_key' => array('default' => Str::random('alnum', 6) ),
'a_key' => array('default' => Str::random('alnum', 6) ),
'created_at',
'updated_at'
);
Thanks!!
Your actual problem here is that you can't perform function calls when making static assignments in PHP. How to initialize static variables
Ok, I used an observer to do that.
/classes/observer/session.php
<?php
namespace Orm;
use Str;
class Observer_Session extends Observer {
public function after_create(Model $session) {
$session->v_key = Str::random('alnum', 6);
$session->a_key = Str::random('alnum', 6);
}
/classes/model/session.php
To dynamically set default values, you can override the forge method in your session model:
public static function forge($data = array(), $new = true, $view = null, $cache = true)
{
$data = \Arr::merge(array(
'v_key' => \Str::random('alnum', 6),
'a_key' => \Str::random('alnum', 6),
), $data);
return parent::forge($data, $new, $view, $cache);
}

CakePHP Not Loading Behaviors of Related Models on Plugin

I'm programming a plugin for a CakePHP app that has the following Models:
Preregistry Model
App::uses('PreinscriptionAppModel', 'Preinscription.Model');
class Preregistry extends PreinscriptionAppModel {
public $hasMany = array(
'Relative'
);
public $actsAs = array(
'Date' => array(
'birthday' => array(
'format' => '%d/%m/%Y'
),
'registry_date' => array(
'format' => '%d/%m/%Y'
)
)
);
}
Relative Model
App::uses('PreinscriptionAppModel', 'Preinscription.Model');
class Relative extends PreinscriptionAppModel {
public $name = 'Relative';
public $actsAs = array(
'Date' => array(
'birthday' => array(
'format' => '%d/%m/%Y'
)
)
);
public $belongsTo = array(
'Preregistry'
);
}
The Relevant part of the Controller is:
<?php
App::uses('PreinscriptionAppController', 'Preinscription.Controller');
class PreregistriesController extends PreinscriptionAppController {
public function add() {
$preregistryDateConfig = $this->Preregistry->getDateConfig();
$relativeDateConfig = $this->Preregistry->Relative->getDateConfig();
}
}
The problem i have is when calling $this->Preregistry->Relative->getDateConfig(); the Date Behavior is not loaded on the Relative model so it throws a MySQL error because the model doesn't have a getDateConfig() method.
When i check if the Behavior is loaded with $this->Preregistry->Relative->Behaviors->loaded('Date'); i get FALSE back.
For some reason the Behavior is only loaded in the Preregistry model but not on the Relative model. I also have tried to load the Behavior on the fly to no success.
If someone could tell me a workaround for this problem i will be very glad.
If you need more code or anything feel free to ask.
Thanks!
I'm pretty sure debug($this->Preregistry->Relative) will show that Relative is an instance of AppModel.
This is because you are missing the proper plugin name in your associations, it should be:
public $hasMany = array(
'Preinscription.Relative'
);
and
public $belongsTo = array(
'Preinscription.Preregistry'
);
otherwise CakePHP won't grab the models from the plugin, but create an instance of AppModel for the associations instead (in case there are no Relative respective Preregistry in any of the configured model locations), which is then of course missing your Date behavior.
See also http://book.cakephp.org/2.0/en/plugins.html#plugin-models

Categories