Extending Sentry 2 Models from a Base Eloquent class - php

Currently i have all my models extending a base class called "Base"
Base extends Eloquent
the problem is i use Sentry 2 for user authentication and groups thus my two of my models User and Group extend their respective Sentry base model SentryUserModel and SentryGroupModel.
I cannot figure out a way to have these two models: User, Group extend my Base model

You could make your User and Group models extend SentryUserModel and SentryGroupModel respectively then extend Base model using a magic function.
Code:
class User extends SentryUserModel
{
private $base;
function __construct()
{
$this->base = new Base();
}
// fake "extends Base" using magic function
public function __call($method, $args)
{
$this->base->$method($args[0]);
}
}
class Group extends SentryGroupModel
{
private $base;
function __construct()
{
$this->base = new Base();
}
// fake "extends Base" using magic function
public function __call($method, $args)
{
$this->base->$method($args[0]);
}
}

Related

I haveto write methods of same functionality again and again for CRUD (Create , Read , Update , Delete) *new in laravel*

public function create() { $Gallery= GalleryModel::all(); return view('admin.gallery',compact('Gallery')); }
public function video() { $Video= VideoModel::all(); return view('admin.video',compact('Video')); }
public function team() { $Team = TeamModel::all(); return view('admin.team',compact('Team')); }
Is where is any way to make single method for different pages
There are many of ways to do that. The general idea is to use Traits.
// ControllerTrait.php
trait ControllerTrait {
// Here you include all yor controller's methods
}
Then, in every controller you use your trait
// YourController.php
class YourController extends Controller {
use ControllerTrait;
// The rest of your controller's code
}
You can even go further if you consider classes inheritance:
You could create a base controller like this:
// MyBaseController.php
class BaseController extends Controller {
use ControllerTrait; // <= you can mix the strategies for more power
// All your BaseController's methods
}
An then let your controllers extend from the base one instead:
// YourController.php
class YourController extends BaseController {
//
}
You could, in the end, just edit you BaseController and your ControllerTrait and ease your life a lot.
NOTE: Editted because you werer talking about Controllers and I was thinking about Models, but you can surely use the same principle for managing your models.
NOTE 2: Traits are better for methods that really will work as default for all controllers, and keep in the BaseModel those that will need to be customized in any of the inheriting controllers. For example:
// MyBaseController.php
class BaseController extends Controller {
protected function a($request) {
//
}
}
// YourController.php
class YourController extends BaseController {
protected function a($request) {
$request = $modifiedRequest; // You can modify the inputs
parent::a($request); // <== Execute the parent method;
}
}

How to correctly extend and use other interfaces?

I'm trying to make use of a base interface for all my other interfaces as follows:
Base interface
<?php
namespace App\Repositories\Data;
interface IDataRepository
{
public function getAll();
public function getById($id);
public function create($model);
public function update($model);
public function delete($id);
}
Implemented base interface
<?php namespace App\Repositories\Data;
use Illuminate\Database\Eloquent\Model;
class DataRepository implements IDataRepository
{
// model property on class instances
protected $model;
// Constructor to bind model to repo
public function __construct(Model $model)
{
$this->model = $model;
}
// Get all instances of model
public function getAll()
{
return $this->model->all();
}
// create a new record in the database
public function create($model)
{
return $this->model->create($model);
}
// update record in the database
public function update($model)
{
$record = $this->find($model.id);
return $record->update($model);
}
// remove record from the database
public function delete($id)
{
return $this->model->destroy($id);
}
// show the record with the given id
public function getById($id)
{
return $this->model-findOrFail($id);
}
}
The interface where i'm trying to make use of the base interface
<?php
namespace App\Repositories;
use App\Repositories\Data\IDataRepository;
interface ITestRepository extends IDataRepository
{
}
implementation
<?php namespace App\Repositories;
use App\Library\Classes\Test;
use Illuminate\Database\Eloquent\Model;
class TestRepository implements ITestRepository
{
}
In my controller i'm trying to just call test repository so i can use all the base repository functions:
class TestController extends Controller
{
protected $testRepository;
public function __construct(Test $test)
{
$this->testRepository = new TestRepository($test);
}
public function index()
{
$data['testData'] = $this->testRepository->getAll();
return view('test', $data);
}
}
But i get the following error:
Class App\Repositories\TestRepository contains 5 abstract methods and
must therefore be declared abstract or implement the remaining methods
My application works fine if i only make use of my base interface and pass through a model. What would be the correct way to share functions from my base interface across all my other interfaces, so as to prevent code duplication? I appreciate any help.
I think that a Trait which will contains all methods of your interface declaration is the best choice. Something like (not sure about logic):
namespace App\Repositories;
trait TDataRepository
{
// model property on class instances
protected $model;
// Constructor to bind model to repo
public function __construct(Model $model)
{
$this->model = $model;
}
// Get all instances of model
public function getAll()
{
return $this->model->all();
}
// create a new record in the database
public function create($model)
{
return $this->model->create($model);
}
// update record in the database
public function update($model)
{
$record = $this->find($model.id);
return $record->update($model);
}
// remove record from the database
public function delete($id)
{
return $this->model->destroy($id);
}
// show the record with the given id
public function getById($id)
{
return $this->model-findOrFail($id);
}
}
And then just use it for classes with base interface:
namespace App\Repositories;
use App\Library\Classes\Test;
use Illuminate\Database\Eloquent\Model;
class TestRepository implements ITestRepository
{
use TDataRepository;
}
Also there are some other options:
abstract class with methods for base interface but it not so flexible like trait,
composition but you should change base idea and create a new entity for composition.
<?php
namespace App\Repositories;
use App\Interfaces\ITestRepository;
class TestRepository implements ITestRepository
{
public function getAll()
{
// TODO: Implement getAll() method.
}
public function getById($id)
{
// TODO: Implement getById() method.
}
public function create($model)
{
// TODO: Implement create() method.
}
public function update($model)
{
// TODO: Implement update() method.
}
public function delete($id)
{
// TODO: Implement delete() method.
}
}
Class must be declared abstract or implement methods 'getAll', 'getById', 'update', 'create', 'delete'
So All the method is by default abstract method in interface and you have to define all method in this class.
The class TestRepository should not implement any interface, but extend DataRepository:
<?php namespace App\Repositories;
use App\Repositories\Data\DataRepository;
class TestRepository extends DataRepository
{
}
DataRepository contains already the implementation of the interface IDataRepository. When you create a class implementing ITestRepository you will have to define the implementation of all the methods in the interface (which are the same as the base interface, in your case).

How Can I Use Global Scope in Laravel Query Builder? (No Eloquent Model)

I'm working with too many mysql large views. I don't want to use Eloquent Model for the views.
I created "ViewBalance extends Illuminate\Support\Facades\DB". Everything worked as I wanted.
But i need to set init() method for company scope.
How can I use the global scope without init() method?
ViewModel
<?php
namespace App\Models\Views;
use App\Facades\CoreService;
use Illuminate\Support\Facades\DB;
class ViewBalance extends DB
{
const COMPANY_COLUMN = 'company_id';
const TABLE = 'view_balances';
public static function init()
{
return parent::table(self::COMPANY_COLUMN)
->where(self::COMPANY_COLUMN, CoreService::companyId());
}
}
In Controller
<?php
$data = ViewBalance::init()->get(); // Worked!
I have answered my own question. Because, I don't want to edit my question for more complicate. I want to talk about a solution to this problem.
I added $table_view variable and getView() method in Laravel model. If you want, you can create trait for clean codes.
It can be accessed easily views. Also it is part of the main model.
For example;
Laravel Basic Account Model
class Account extends Model {
protected $table = 'accounts';
protected $table_view = 'view_accounts';
public function getView()
{
return \DB::table($this->table_view)->where('global_scope', 1);
}
}
Laravel Account Controller
class AccountController extends Controller {
public function index()
{
$items = (new Account)->getView()->paginate(20);
}
}
public function scopeActive($query)
{
return $query->where('active', true);
}
or
public function scopeInactive($query)
{
return $query->where('active', false);
}

Laravel 4 dynamic model call

I'm developing an API to acces some data on my database. I'm creating a controller for each part of the API. For example, I will have a controller to attend API calls to get a film list (FilmsController) and other controller to attend API calls to get a director list (DirectorsController)
Each controller will have a basic set of methods (getList, getInfo) so I made an ApiController to use as the base for the others. In the ApiController I have the basic set of methods but I have to call the models in non very polite way.
I'm I missing something? Is there any other way to call the models dynamically? I'm using the controllers wrong?
Here is the code, thanks.
class ApiController extends BaseController {
protected $model = '';
public function getList()
{
$items = call_user_func(array($this->model,'all'));
return Response::json($items);
}
...
}
And the FilmsController
class FilmsController extends ApiController {
protected $model = 'Film';
}
Am I going with a bad design?
If you really want to bind model to controller, it would be better to use Laravel IoC container and its automatic resolution feature.
class ApiController extends BaseController {
protected $model;
public function getList()
{
$items = $this->model->all();
return Response::json($items);
}
}
class FilmsController extends ApiController {
public function __construct(Model $model)
{
$this->model = $model;
}
}
Find more about this in documentation
why you call model using variable and use call_user_func function
you can just create ApiController as abstract class and you override the basic set of methods (getList, getInfo) into FilmsController and DirectorsController then you can use Film Model
ApiController:
class ApiController extends BaseController {
public function getList()
{
}
FilmsController:
class FilmsController extends ApiController {
public function getList()
{
$items = Film::all();
return Response::json($items);
}
}

Table prefix configuration in Phalcon Model

I would like to set up a table prefix for all my models, since this is how it is designed in the database.
How can I achieve that?
You can override the getSource method to set the prefix:
class Users extends Phalcon\Mvc\Model
{
public function getSource()
{
return 'my_' . 'users';
}
}
Or, you can set a base model class to set the table prefix for all models:
class BaseModel extends Phalcon\Mvc\Model
{
public function getSource()
{
return 'my_' . strtolower(get_class($this));
}
}
and extend all models from that
class Users extends BaseModel
{
}
or in PHP 5.4 you can create a trait:
trait CustomPrefix
{
public function getSource()
{
return 'my_' . strtolower(get_class($this));
}
}
then in your model:
class Users extends Phalcon\Mvc\Model
{
use CustomPrefix;
}
Source
Also, if you have tables with underscores "_" you could write it like that:
public function getSource()
{
return 'my_'.strtolower(preg_replace('/([a-z])([A-Z])/', '$1_$2', get_class($this)));
}
you can also add all your settings to initialize function. If you have any connection between models like one-one many-many one-many you will define them also in initialize method.
class Robots extends \Phalcon\Mvc\Model
{
public function initialize()
{
$this->setSource("the_robots");
}
}

Categories