Laravel Excel passing argument - php

I'm trying to pass argument to filter the data I want to export to Excel.
This is my code :
class UnitExport implements FromCollection
{
public function collection($proj_id)
{
return Unit::where('project_id', $proj_id);
}
}
class UnitController extends Controller
{
public function index($proj_id)
{
return view('dev-admin.projects.units.index', ['proj_id' => $proj_id]);
}
public function unitExcelExport($proj_id)
{
return Excel::download(new UnitExport($proj_id), 'Unit.xlsx');
}
}
When try this it says i receive an error says:
Declaration of
App\Http\Controllers\Developer\Admin\UnitExport::collection($proj_id)
must be compatible with
Maatwebsite\Excel\Concerns\FromCollection::collection()

You can't pass your argument directly to your collection function. Try this.
class UnitExport implements FromCollection
{
protected $proj_id;
public function __construct($proj_id)
{
$this->proj_id = $proj_id;
}
public function collection()
{
return Unit::where('project_id', $this->proj_id)->get();
}
}

Related

how to create a unique key for caching query in laravel

I used repository in a project that caching all queries.
there's a BaseRepository.
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Cache;
class BaseRepository implements BaseRepositoryInterface{
protected $model;
protected int $cacheDuration = 600; //per seconds
public function __construct(Model $model)
{
return $this->model = $model;
}
public function paginate(int $paginate,string $cacheKey)
{
return Cache::remember($cacheKey,$this->cacheDuration , function () use ($paginate) {
return $this->model->latest()->paginate($paginate);
});
}
// other methods ...
}
then i used this repository in my service
PostService:
use Illuminate\Support\Facades\App;
class PostService{
public PostRepositoryInterface $postRepository;
public function __construct()
{
$this->postRepository = App::make(PostRepositoryInterface::class);
}
public function paginate(int $paginate, string $cacheKey)
{
return $this->postRepository->paginate($paginate,$cacheKey);
}
}
finally i using the PostService in my controller
PostController:
class PostController extends Controller{
public PostService $postService;
public function __construct()
{
$this->postService = App::make(PostService::class);
}
public function index()
{
string $cacheKey = "posts.paginate";
return $this->postService->paginate(10);
}
}
the index method will return top 10 latest record correctly. now i need to create a unique CacheKey for all Repository queries. for example
TableName concat FunctionName // posts.paginate
so i can use this code into all method of Repository
public function paginate(int $paginate)
{
$cacheKey = $this->model->getTable().__FUNCTION__;
return Cache::remember($cacheKey,$this->cacheDuration , function () use ($paginate) {
return $this->model->latest()->paginate($paginate);
});
}
this is fine. but the problem is that this code repeat in all the method of this class.
if i use this code in another class, method name's will be incorrect.
What do you suggest to prevent duplication of this code?
I solve this problem by passing function name to another class
I created CacheKey class:
class CacheKey{
public static function generate(Model $model, $functionName):string
{
return $model->getTable()."_".$functionName;
}
}
Then in any method of repository we can use this helper class as follows:
$cacheKey = CacheKey::generate($this->model,__FUNCTION__);
you can easily use magic method in this way:
class CacheService {
private const $cacheableMethods = ['paginate'];
private $otherSerivce;
public __construct($otherSerivce) {
$this->otherSerivce = $otherSerivce;
}
public __get($method, $args) {
if(!in_array($method, static::$cachableMethods)) {
return $this->otherSerivce->{$method}(...$args);
}
return Cache::remember(implode([$method, ...$args], ':'), function () {
return $this->otherSerivce->{$method}(...$args);
});
}
}

Error when implementing the contract in Laravel 5.2

I am following this link to implement it
I did below steps to implement the Contract in my existing class.
Below is the class where I will write some logic also before sending it to controller
namespace App\Classes\BusinessLogic\Role;
use App\Classes\DatabaseLayer\Role\RoleDb;
use App\Classes\Contract\Role\IRole;
class RoleBL implements IRole {
public function All() {
return (new RoleDb())->All();
}
}
Database Function
namespace App\Classes\DatabaseLayer\Role;
class RoleDb {
public function All() {
$Roles = \App\Models\Role\RoleModel
::all();
return $Roles;
}
}
Interface
namespace App\Classes\Contract\Role;
interface IRole {
public function All();
}
Service Provider class
namespace App\Providers\Role;
class RoleServiceProvider extends \Illuminate\Support\ServiceProvider {
public function register()
{
$this->app->bind('App\Classes\Contract\Role\IRole', function($app){
return new \App\Classes\BusinessLogic\Role\RoleBL($app['HttpClient']);
});
}
}
Finally in config/app.php in provider wrote below line.
App\Providers\Role\RoleServiceProvider::class
Controller - Constructor
protected $roles;
public function __construct(\App\Classes\Contract\Role\IRole $_roles) {
parent::__construct();
$roles = $_roles;
}
Controller Action method
public function index(IRole $roles) {
$RoleTypes = $roles->All();
}
So far everything works fine if I keep Interface as parameter in method.
if I try to use the variable $roles in index method and remove the variable, it is always null.
Please guide me if I missed anything?
You incorrectly assign the $roles property in your __construct() method.
Replace
$roles = $_roles;
with
$this->roles = $_roles;
and then in your index method do:
$RoleTypes = $this->roles->All();

Laravel doesn't remember class variables

I have a class in Laravel with a class variable that holds and object
class RegisterController extends Controller {
public $company;
When i set the variable in my index method all goes well
public function index($id = null) {
$this->company = new Teamleader\Company;
When I try to access $this->company from another method it returns
null
This is my full code
class RegisterController extends Controller {
public $company;
public function index($id = null)
{
$this->company = new Teamleader\Company;
// returns ok!
dd($this->company);
return view('register.index');
}
public function register()
{
// returns null
dd($this->company);
}
}
Am I missing something?
Thank you!
You are not __constructing() the class, you are just assigning variable inside a function inside a class, which means it is encapsulated into that function inside that class.
So if you would like to make $this->company global in class, you could use
public function __construct() {
$this->company = new Teamleader\Company;
}
In Laravel 5 you can inject a new instance of Teamleader\Company into the methods you need it available in.
use Teamleader\Company;
class RegisterController extends Controller {
public function index($id = null, Company $company)
{
dd($company);
}
public function register(Company $company)
{
dd($company);
}
}
For Laravel <5 dependency inject into the constructor.
use Teamleader\Company;
class RegisterController extends Controller {
protected $company;
public function __construct(Company $company)
{
$this->company = $company;
}
public function index($id = null)
{
dd($this->company);
}
public function register()
{
dd($this->company);
}
}
Dependency injection is better than manual invocation as you can easily pass a mock object to this controller during testing. If you're not testing, maybe someone else will be in the future, be kind. :-)

Not work UPDATE MYSQL

I have mystical error with MySQL query. I'm using CI php-framework.
This is my function in controller:
public function editParam($id_article_params='')
{
if(IS_AJAX)
{
$this->load->model('Article_params_model','article_params');
$this->article_params->updateSizeById($id_article_params,$_GET['size']);
}
}
Article_params model:
class Article_params_model extends CI_Model
{
public function updateSizeById($id_article_params,$size)
{
$this->db->query("UPDATE article_params SET size='".$size."' WHERE id_article_params='".$id_article_params."'");
}
}
I'm trying to get error but error not isset. For example, next function also in Article_params_model but work!
public function all()
{
return $this->db->query("SELECT * FROM article_params");
}
In Article_params model put below code.
class Article_params_model extends CI_Model
{
public function updateSizeById($id_article_params,$size)
{
$this->db->where('id_article_params', $id_article_params);
$this->db->update('article_params', $size);
}
}
class Article_params_model extends CI_Model
{
public function updateSizeById($id_article_params,$size)
{
$this->db->where('id_article_params', $id_article_params);
$this->db->update('article_params', $size);
}
}

Error __construct() must be an instance of Interface, none given

I'm developing a package for Laravel and I'm getting an error which I can't figure out how to fix:
Argument 1 passed to Cartalini\Drayman\Drayman::__construct() must be an instance of Cartalini\Drayman\Repositories\UserRepositoryInterface, none given, called in /Applications/MAMP/htdocs/l4/app/controllers/HomeController.php on line 10 and defined
Here's my code...
namespace Cartalini\Drayman;
use Cartalini\Drayman\Repositories\UserRepositoryInterface;
class Drayman
{
protected $user;
public function __construct(UserRepositoryInterface $user)
{
$this->user = $user;
}
public function deliverBeer()
{
return $this->user->all();
}
}
UserRepository...
namespace Cartalini\Drayman\Repositories;
class UserRepository implements UserRepositoryInterface
{
public function all()
{
return User::all();
}
}
UserRepositoryInterface...
namespace Cartalini\Drayman\Repositories;
interface UserRepositoryInterface
{
public function all();
}
Service provider...
public function register()
{
$this->app->bind('Cartalini\Drayman\Repositories\UserRepositoryInterface', 'Cartalini\Drayman\Repositories\UserRepository');
}
And finally my controller...
use Cartalini\Drayman\Drayman as Drayman;
class HomeController extends BaseController
{
public function showWelcome()
{
$drayman = new Drayman;
return $drayman->deliverBeer();
}
}
Can anyone help me to debug this please?
In your showWelcome function:
public function showWelcome()
{
// need to pass a UserRepositoryInterface object here:
$drayman = new Drayman;
return $drayman->deliverBeer();
}
Since you did not pass a UserRepositoryInterface object that your code requires you get that error.
it might be a to late, but i had the same problem and the reason was my concrete class didn't implement it's corresponding interface class. after implementing it, all went well.
although you are correctly implementing it, so this error might have a few reason, which one of them is what i described.

Categories