Best things from Django on our favourite php
With composer
{
"require": {
"buldezir/dja_orm": "dev-master"
}
}
php composer.phar install
or php composer.phar require buldezir/dja_orm:dev-master
Create models manual
use Dja\Db\Model\Model;
class User extends Model
{
protected static $fields = array(
'user_id' =>['Auto'],
'email' =>['Char'],
'password' =>['Char'],
'full_name' =>['Char', 'default' => ''],
'date_added' =>['DateTime', 'autoInsert' => true],
'date_updated' =>['DateTime', 'autoUpdate' => true],
'is_active' =>['Bool'],
'timezone' =>['Char'],
'role' =>['ForeignKey', 'relationClass' => 'Role'],
);
}
class Role extends Model
{
protected static $fields = array(
'role_id' =>['Auto'],
'name' =>['Char'],
'is_active' =>['Bool'],
'can_do_smth1' =>['Bool', 'default' => false],
'can_do_smth2' =>['Bool', 'default' => false],
'can_do_smth3' =>['Bool', 'default' => false],
);
}
$creation = new \Dja\Db\Creation($dbConn, ['User', 'Role']);
$creation->processQueueCallback(function (\Dja\Db\Model\Metadata $metadata, \Doctrine\DBAL\Schema\Table $table, array $sql, \Doctrine\DBAL\Connection $db) {
foreach ($sql as $sqlstmt) {
$db->exec($sqlstmt);
}
});
Or from database structure
$dbConn = \Doctrine\DBAL\DriverManager::getConnection(array(
'driver' => 'pdo_pgsql',
'dbname' => '',
'user' => '',
'password' => '',
'host' => 'localhost',
));
$dbi = new Dja\Db\Introspection($dbConn, $dbConn->getSchemaManager()->listTableNames());
$dbi->setPrefix('Model');
$dbi->processQueueCallback(function ($tableName, $modelClassName, $code) {
file_put_contents('models.php', $code, FILE_APPEND);
});
Lookup
// single object
$user1 = User::objects()->get(1);
// queryset
$allUsers = User::objects()->all();
// queryset with auto join and filters
$activeUsersWithRoles = User::objects()->selectRelated(['depth' => 3])->filter(['is_active' => 1, 'user_id__in' => [1,2,3,4,5]]);
foreach ($activeUsersWithRoles as $user) {
// Role object without quering db
$role = $user->role;
$role->is_active = 1;
$role->save();
}
// auto backwards relation
$role1 = Role::objects()->get(1);
$roleUsers = $role1->users_set; // this is queryset
$roleUsersWithOrdering = $roleUsers->order('-full_name');
// get result as key=>val list
$dict = User::objects()->filter(['is_active' => true])->valuesList('name', 'user_id');
foreach($dict as $userId => $userName){}
// raw query
$iteratorOverModels = User::objects()->raw('SELECT * FROM users');
$iteratorOverArrays = User::objects()->raw('SELECT * FROM users')->returnValues();
// raw query with placeholders and autoreplacements
$iteratorOverArrays = User::objects()->raw('SELECT :pk, :role FROM :t WHERE :pk < :maxPK', [':maxPK' => 10])->returnValues(); // = 'SELECT user_id, role_id FROM users WHERE user_id < 10'
// iterate fetching $chunkSize chunks
$chunkSize = 1000;
foreach (chunkedIterator($allUsers, $chunkSize) as $k => $v) {
// for example if we have 5000 users there will be 5 db queries, in this foreach
}
U can write your own fields
class JsonField extends BaseField
{
public function cleanValue($value)
{
return is_array($value) ? $value : json_decode($value);
}
public function dbPrepValue($value)
{
return json_encode($value);
}
public function getDefault()
{
return [];
}
}
class TestModel
{
protected static $fields = array(
...
'options' =>['JsonField'],
);
}
$obj = new TestModel;
$obj->options['ololo'] = 'jjjjjj';
$obj->save(); // will store json string in text field
And getters and setters of course
class TestModel2 extends TestModel
{
...
public function setOptions($value)
{
if (!is_array($value)) {
throw new \Exception('GTFO');
}
$this->_set('options', $value);
}
public function getOptions()
{
return array_merge($this->_get('options'), get_global_options());
}
}
Abstract models
abstract class BaseObjectModel
{
protected static $fields = array(
'date_added' => ['DateTime', 'autoInsert' => true],
'date_updated' => ['DateTime', 'autoUpdate' => true],
'user' => ['ForeignKey', 'relationClass' => 'User'],
);
}
class Article extends BaseObjectModel
{
protected static $fields = array(
'header' => ['Char'],
'text' => ['Text'],
'slug' => ['Slug', 'prepopulate_field' => 'header'],
);
}
// So Article model will have fields: header, text, slug, date_added, date_updated, user