I have multiple DAO classes (or Repository classes in Laravel jargon).
<?php
namespace App\Repository;
class CompanyRepository extends RepositoryFactory
{
public function getCompany($id)
{
$q = "SELECT COMPANY FROM `COMPANIES` WHERE ID > :id1";
$result = DB::select($q, ["id1" => $id]);
return $result;
}
}
?>
<?php
namespace App\Repository;
class ArticleRepository extends RepositoryFactory
{
public function createArticle($title, $summary)
{
….
}
}
?>
Now I would like for one class to include once all my Repositories (30-40 Repositories) with a class such as RepositoryInclude
<?php
namespace App\Repository;
use App\Repository\ArticleRepository;
use App\Repository\CompanyRepository;
use ….
class RepositoryInclude
{
}
?>
so that from my Controller I could simply:
use App\Repository\RepositoryInclude;
class MYController extends Controller
{
public function __construct(CompanyRepository $companyRepository)
{
$this->companyRepository = $companyRepository;
}
public function index()
{
$companyNameList = $this->companyRepository->getCompany();
}
}
How can I do that? apparently nesting classes with a hierarchy of "use" doesn't work as if I nest a series of "include_once".
PS: I would like to use common PHP language techniques which I can reuse in the future and no Laravel "hacks", expecially if they involve command line commands which I'm avoiding as much as possible.
Related
I am currently updating a project from CakePHP 3 to CakePHP 4, and in this project I have a Trait that implements a "common" virtual property that some of the entities need.
<?php
namespace App\Model\Table;
use Cake\ORM\Table;
class NewsTable extends Table
{
public function initialize(array $config): void
{
parent::initialize($config);
$this->setTable('news');
$this->setPrimaryKey('id');
// more config here...
}
}
<?php
namespace App\Model\Entity;
use Cake\ORM\Entity;
class News extends Entity
{
use SitemapTrait;
protected $_virtual = ['sitemap']; // this is the virtual property that the trait should take care of
}
<?php
namespace App\Model\Entity;
use Cake\ORM\TableRegistry;
trait SitemapTrait
{
protected function _getSitemap()
{
$table = TableRegistry::getTableLocator()->get($this->getSource());
// more logic here...
}
}
The problem is that, on the _getSitemap() method, $this->getSource() returns a generic Cake\ORM\Table object, rather than a App\Model\Table\NewsTable object as I would expect, so everything that should happen afterward will not work.
I also wrote a simple command to check what happens when getSource() is called directly on an entity, and in this case I get the correct result, so the problem seems to be specifically related to it being called inside a Trait:
<?php
namespace App\Command;
use Cake\Command\Command;
use Cake\Console\ConsoleIo;
use Cake\Console\Arguments;
use Cake\ORM\TableRegistry;
class OrmTestCommand extends Command
{
protected $newsTable;
public function __construct()
{
$this->newsTable = TableRegistry::getTableLocator()->get('News');
}
public function execute(Arguments $args, ConsoleIo $io)
{
$news = $this->newsTable->find('all')
->first();
print_r($news->getSource());
}
}
In this case I correctly get a App\Model\Table\NewsTable object.
I don't get why this broke going from CakePHP 3.5.18 to 4.3.11. Do I need some extra config in my model? What am I doing missing or doing wrong?
Recently I've been learning to use Slim 3 and eloquent.
What I'm trying to do is this (if it's even possible that is)
So I have a Model.php file
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model as Model;
use Illuminate\Database\Capsule\Manager as DB;
class Course extends Model{
protected $table = "courses";
public function GetCourses(){
}
}
?>
And my Controller.php
<?php
namespace App\Controllers;
use App\Models\Course;
use Slim\Views\Twig as View;
class CourseController extends Controller{
public function index($request,$response){
return $this->view->render($response,'course/CourseNew.twig',$data);
}
}
?>
So my question is inside the Model.php is it possible to call another table somehow?
I've already called mine with protected $table = "courses"; I kind of understand that the table i defined is for the whole Class but is there a way or a workaround?
The main idea here is that i have some database tables that are very small and are not worth making another Model files for them
If this is not possible what is the alternative?
Do I have to make another Model file and call it on top of my controller where i need it use namespace App\Models\"new_model";
I would recommend to separate the data structure from the data access logic. For example: put the code for the database queries into a Repository. A repository does not care where the data comes from (table x or table y).
Example
<?php
namespace App\Repository;
use App\Model\Course;
class CourseRepository extends Repository
{
public function __construct(Connection $db)
{
$this->db = $db;
}
public function findCourceById(int $courseId): ?Course
{
// execute query here
//$this->db->....
return $course;
}
public function findSomething(): array
{
// execute query here
//$this->db->....
return $rows ?: [];
}
}
I need an example of where to exactly create the file, to write to it, and how to use the functions declared in the trait. I use Laravel Framework 5.4.18
-I have not altered any folder in the framework, everything is where it corresponds-
From already thank you very much.
I have Create a Traits directory in my Http directory with a Trait called BrandsTrait.php
and use it like:
use App\Http\Traits\BrandsTrait;
class YourController extends Controller {
use BrandsTrait;
public function addProduct() {
//$brands = Brand::all();
// $brands = $this->BrandsTrait(); // this is wrong
$brands = $this->brandsAll();
}
}
Here is my BrandsTrait.php
<?php
namespace App\Http\Traits;
use App\Brand;
trait BrandsTrait {
public function brandsAll() {
// Get all the brands from the Brands Table.
$brands = Brand::all();
return $brands;
}
}
Note: Just like a normal function written in a certain namespace, you can use traits as well
Trait description:
Traits are a mechanism for code reuse in single inheritance languages such as PHP. A Trait is intended to reduce some limitations of single inheritance by enabling a developer to reuse sets of methods freely in several independent classes living in different class hierarchies. The semantics of the combination of Traits and classes is defined in a way which reduces complexity and avoids the typical problems associated with multiple inheritance and Mixins.
The solution
Make a directory in your App, named Traits
Create your own trait in Traits directory ( file: Sample.php ):
<?php
namespace App\Traits;
trait Sample
{
function testMethod()
{
echo 'test method';
}
}
Then use it in your own controller:
<?php
namespace App\Http\Controllers;
use App\Traits\Sample;
class MyController {
use Sample;
}
Now the MyController class has the testMethod method inside.
You can change the behavior of trait methods by overriding them it in MyController class:
<?php
namespace App\Http\Controllers;
use App\Traits\Sample;
class MyController {
use Sample;
function testMethod()
{
echo 'new test method';
}
}
Let's look at an example trait:
namespace App\Traits;
trait SampleTrait
{
public function addTwoNumbers($a,$b)
{
$c=$a+$b;
echo $c;
dd($this)
}
}
Then in another class, just import the trait and use the function with this as if that function was in the local scope of that class:
<?php
namespace App\ExampleCode;
use App\Traits\SampleTrait;
class JustAClass
{
use SampleTrait;
public function __construct()
{
$this->addTwoNumbers(5,10);
}
}
I am writing system for players where I use Laravel freamwork (just for learn) and I have question for more experience developer. I have one function which return me some data to view. I use this function in 3 controllers (but i copy and paste this function to each Controller files) and can I just put this function in one file and then use it in these 3 controllers? How can I use the same function in diffrent controller without copy and past?
You can also use Traits to share methods, however, traits are more usually for describing characteristics and types.
You should create a utility class, or use consider an abstract controller class if this is desired.
You can create Base Controller:
<?php
namespace App\Http\Controllers;
class BaseController
{
protected $playersRepository;
public function __construct(PlayersRepository $playersRepository)
{
$this->playersRepository = $playersRepository;
}
}
Which is injected with a repository object:
<?php
namespace App\Http\Controllers;
class PlayersRepository
{
public function getPlayers()
{
return Player::all();
}
}
Which has a common method, that can be used in more than one extended controller:
Games
<?php
namespace App\Http\Controllers;
class Games extends BaseController
{
public function index()
{
return view('games', ['players' => $this->playersRepository->getPlayers()]);
}
}
Matches
<?php
namespace App\Http\Controllers;
class Matches extends BaseController
{
public function show()
{
return view('matches', [
'matches' => $matches,
'players' => $this->playersRepository->getPlayers()
]);
}
}
Create module (util) or override main Controller class.
I've set up a test parent class in my Symfony 2 controller as follows:
<?php
namespace Zetcho\AmColAnBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class BaseController extends Controller
{
public function validateUser()
{
$user['first_name'] = "Name";
$user['signin'] = true;
return $user;
}
}
class DefaultController extends BaseController
{
public function indexAction()
{
$user = $this->validateUser();
$displayParms['user'] = $user;
return $this->render('ZetchoAmColAnBundle:Default:index.html.twig',$displayParms);
}
}
The code is in src/Zetcho/AmColAnBundle/Controller/DefaultController.php
The test code works. I'd now like to move the parent class (BaseController) out of the controller file to its own so I can reuse it in my other controllers. I want to put it in the same directory as the other controllers and I'd like to declare it the same way as the Controller in the use statement above. What's the best/accepted way to do this in Symfony 2?
You do this in Symfony2 exactly the same way as you would with any PHP class. Split your classes into separate files like this:-
src/Zetcho/AmColAnBundle/Controller/BaseController.php
namespace Zetcho\AmColAnBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class BaseController extends Controller
{
public function validateUser()
{
$user['first_name'] = "Name";
$user['signin'] = true;
return $user;
}
}
src/Zetcho/AmColAnBundle/Controller/DefaultController.php
namespace Zetcho\AmColAnBundle\Controller;
use Zetcho\AmColAnBundle\Controller\BaseController;
class DefaultController extends BaseController
{
public function indexAction()
{
$user = $this->validateUser();
$displayParms['user'] = $user;
return $this->render('ZetchoAmColAnBundle:Default:index.html.twig',$displayParms);
}
}
Its really quite simple once you know how. Remember that controllers in symfony2 are just normal PHP classes, there is nothing special about them.