Codeigniter + design patterns - codeigniter

Can we use design patterns with Codeigniter? Can we create abstract classes, interfaces and extend them? If I can create those classes, how can I include them? Should those classes reside inside the controller folder or the model folder?
If possible can someone explain me, how to implement the following design pattern with Codeignitor? How to include the fills and organize them. Appreciate your support. Thanks!
<?php
interface IAccount {
public function get_balance();
}
class Savings_account implements IAccount {
public function get_balance() {
//get account balance
}
}
class Current_account implements IAccount {
public function get_balance() {
//get account balance
}
}
class Bank {
private $acc_type = null;
public function __construct(IAccount $acc) {
$this->acc_type = $acc;
}
public function get_balance() {
return $this->acc_type->get_balance();
}
}
//Client code in a contoller
$bank = new Bank(new Savings_account());
echo $bank->get_balance();
//or
$bank = new Bank(new Current_account());
echo $bank->get_balance();
?>

Related

bind abstract class service in provider laravel

Gives an error:
Target [MyVendor\ProductList\ProductServiceInterface] is not instantiable.
ProductServiceInterface
namespace MyVendor\ProductList;
interface ProductServiceInterface
{
public function productList();
public function getProductSpeed();
}
ProductColorService
namespace MyVendor\ProductList\Service;
abstract class ProductColorService implements \MyVendor\ProductList\ProductServiceInterface
{
public function productList()
{
$color = "black";
return $color;
}
}
** ProductSpeedService **
namespace MyVendor\ProductList\Service;
abstract class ProductSpeedService implements \MyVendor\ProductList\ProductServiceInterface {
public function getProductSpeed() {
$speed = 200;
return $speed;
}
}
Provider :
namespace MyVendor\ProductList;
use Illuminate\Support\ServiceProvider;
use MyVendor\ProductList\ProductServiceInterface;
use MyVendor\ProductList\Service\ProductColorService;
class ProductColorServiceProvider extends ServiceProvider
{
public function boot()
{
$this->loadRoutesFrom(__DIR__ . '/routes/color.php');
}
public function register()
{
$this->app->bind('MyVendor\ProductList\ProductServiceInterface','MyVendor\ProductList\Service\ProductColorService');
$this->app->bind('MyVendor\ProductList\ProductServiceInterface','MyVendor\ProductList\Service\ProductSpeedService');
}
}
Whats wrong in this code? Actually I need to override some functions in interface using service. ie each service should override one method.
namespace MyVendor\ProductList\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use MyVendor\ProductList\Models\Product;
use MyVendor\ProductList\ProductServiceInterface;
class ProductListController extends Controller
{
public function index(ProductServiceInterface $product_service)
{
$color = $product_service->productList();
$speed = $product_service->getProductSpeed();
dd($color," = ",$speed);
$product = Product::get();
return view('ProductList::product',compact('product'));
}
}
here productList() in one service and productSpeed() from another service
You can't instantiate abstract classes. The whole point of them is there can never be an instance of them, so if you bind your interface to your abstract class with a method, it simply can never be abstract. Abstract is for classes in inheritance structures you do not want to have the users to create new ones.
So there is no reason for the abstract, abstract is for something like this.
abstract class Vehicle {
protected $wheels;
public function getWheels() {
return $this->wheels;
}
}
class Car extends Vehicle {
protected $wheels = 4;
}
class Bike extends Vehicle {
protected $wheels = 2;
}
You can not make a vehicle as it is not a concrete implementation, as it is a parent class to help with methods shared across two classes. So short version, just remove the abstract keyword. If you don't know why you add it, it is not needed.

How to make binding in Laravel that depends on class and method

I look for the way to make simple binding in Laravel. This binding must depend on class and method that I am using.
That is my User Controller:
class UserController extends Controller {
public function getIndex(SomeClass $someClass) {
return $someClass->action();
}
}
That is my SomeClass:
class SomeClass {
private $number;
public function __construct(int $number) {
$this->number = $number;
}
public function action() {
return "Lorem ipsum ". $this->number;
}
}
I want to make in one binding that will follow the condition
When I use UserController and its the method getIndex then I want to call SomeClass with given param (and the key is that the given param I want to define in that binding.
I tried below example, but it does not work the way I need:
$this->app->when(UserController::class)
->needs(SomeClass::class)
->give(function () {
return new SomeClass(4434);
});
Thanks in advance!

CodeIgniter Has relationship between models

I've been googling on this issue for a quite while and still haven't found a satisfactory answer yet :(
It's a small web-based online game where a player will have a game board and a resource board. What is the best way to include those two classes in the player class to create a has-relationship?
Is there a particular way to do it in CI? or just go with include()?
An alternative is dependancy Injection
class userModel extends CI_Model
{
public function __construct(gameModel $gameModel)
{
var_dump($gameModel instanceof gameModel);
}
}
-
class Controller extends CI_Controller
{
public function method()
{
$this->load->model('gameModel');
// load model with dependancy on gameModel
// or vise-verse
$this->load->model('userModel', new gameModel);
}
}
-
Or like I mention in comments
class userModel extends CI_Model
{
public function method()
{
$gameModel = $this->load->model('gameModel');
}
public function __get($object)
{
$instance =&get_instance();
return $instance->$object;
}
}

ZF2 using FilterProviderInterface to filter class method

I have a model class witch basically is the fields from a database table with getter and setters.
class RealEstate extends BaseModel implements FilterProviderInterface
{
public $cityId;
public $stateId;
...
public $transferFields = array();
public function getFilter()
{
return new MethodMatchFilter('getTransferFields');
}
public function setTransferFields($transferFields)
{
$this->transferFields = $transferFields;
}
public function getTransferFields()
{
return $this->transferFields;
}
...
}
In my BaseTableGateway class I have a method save which takes this model object and extracts the data using get methods into an array.
$hydrator = new ClassMethods(false);
$model_data = $hydrator->extract($model);
I need the getTransferFields() method to bind the object to my form but I dont need it to be in the final array (be excluded while extracting).
public function getFilter()
{
return new MethodMatchFilter('getTransferFields');
}
This method does exactly what I want but only for 1 method. I can't find out how to filter more than 1 method. Does anyone know how this would be achieved?
Simply return a FilterComposite object. The FilterComposite implements FilterInterface and is treated the same as the MethodMatchFilter.
For example:
public function getFilter()
{
$myFilters = new FilterComposite();
$myFilters->addFilter('someParam', new MethodMatchFilter('getSomeParam'));
$myFilters->addFilter('someOtherParam', new MethodMatchFilter('getSomeOtherParam'));
return $myFilters;
}

Wrapper class in MVC3

I want to create a wrapper class so that all queries should not be in controller. Currently select queries are placed in Controller. But I want to create another layer for abstraction.
I already created a viewmodel class. But wrapper class is something else.
How do I do that?
I don't do any queries directly in my controllers. I have a service layer which my controller would call, and each service layer would do a call to the repository to insert, update or delete data or bring back data.
The sample code below uses ASP.NET MVC3 and Entity Framework code first. Lets assume you want to bring back all the countries and use it for whatever reason in your controller/view:
My database context class:
public class DatabaseContext : DbContext
{
public DbSet<Country> Countries { get; set; }
}
My country repository class:
public class CountryRepository : ICountryRepository
{
DatabaseContext db = new DatabaseContext();
public IEnumerable<Country> GetAll()
{
return db.Countries;
}
}
My service layer that calls my repository:
public class CountryService : ICountryService
{
private readonly ICountryRepository countryRepository;
public CountryService(ICountryRepository countryRepository)
{
// Check for nulls on countryRepository
this.countryRepository = countryRepository;
}
public IEnumerable<Country> GetAll()
{
// Do whatever else needs to be done
return countryRepository.GetAll();
}
}
My controller that would call my service layer:
public class CountryController : Controller
{
private readonly ICountryService countryService;
public CountryController(ICountryService countryService)
{
// Check for nulls on countryService
this.countryService = countryService;
}
public ActionResult List()
{
// Get all the countries
IEnumerable<Country> countries = countryService.GetAll();
// Do whatever you need to do
return View();
}
}
There are lots of info on the internet on how to get you data and display it, inserting, editing, etc. A good place to start is at http://www.asp.net/mvc. Work through their tutorials, it will do you good. All the best.

Resources