How to use Sentry with Ardent in Laravel? - php

In my models I use Ardent for self-validating but I have a model where I also need to use Sentry for authentication. So I need to extend Ardent and Sentry too, but I can't because there is no multiple inheritance in PHP. I tried to do it with traits, but traits can't extend. I hardly need both classes, is there a way I can use both of them?

I think the best way to do this would be to copy the entire User model directly from the Sentry folder:
e.g. src/Cartalyst/Sentry/Users/Eloquent/User.php
Copy that file to your models directory, then have it extend Ardent instead of Model since Ardent already extends Model.
This should work -- though there could be some complications or fixes needed to make it work, I'm doing something similar using Toddish/Verify instead of Sentry.

Related

Laravel what is use HasFactory?

I created a model in Laravel. I always noticed the default would be use HasFactory. May I know what exactly does it work. In my understanding from reading documentation, it is for linking to database (I guess?) But I still don't understand how it works exactly.
HasFactory is not to link to the database.
It is a trait that links a Eloquent model to a model factory.
Factories are normally used in testing when wanted test-data for a specific model.
You can read more about factories in Laravel here: https://laravel.com/docs/9.x/database-testing#model-factories and here:
https://laravel.com/docs/9.x/eloquent-factories
The trait ensures that you can instantiate a factory like this:
User::factory()->create();
In older versions of Laravel the trait was not used, and instead a factory had to be instantiated by the global factory helper like this factory(User::class)->create(); but that caused a lot of problems with intellisense in IDE's.

Migration of zf2 to zf3

I have some issues regarding the zf2 to zf3 migration of my application. I've gone through the migration guides and started the migration process as describe there.
According to the migration guide, there is no serviceLocator available into controllers anymore. And I used to use it within each and every controller action to inject the config variable array (located in module.config.php), Doctrine MongoDB DocumentManager and the Doctrine EntityManager into the Models where they are needed. Now I'm getting so many deprecated warnings messages as below;
PHP Deprecated: Usage of
Zend\ServiceManager\ServiceManager::getServiceLocator is deprecated
since v3.0.0; please use the container passed to the factory instead
in
/var/www/html/LeapX/vendor/zendframework/zend-servicemanager/src/ServiceManager.php
on line 169
Since I need to access config variables and inject the Doctrine DocumentManager and Doctrine EntityManager into my Models, I had to call $this->getServiceLocator() within my controllers. Let me know how to fix this issue. Is there any possibility to directly inject these dependencies into my Model classes? Should I need to use factories for Models?
And the other question is when it comes to factories regarding the controllers, Should I need to create individual factory for each and every controller of my application? There are quite a lot of number of controllers spread within few Modules in the application. If I add dedicated factory for each and every controller there will be double the number. Let me know the best way to do this.
From what i have read myself, it is no longer possible to call getServiceLocator() from controllers, they removed it since it promotes antipattern.
Here's a blog post from Matthew himself on this issue:
https://mwop.net/blog/2016-04-26-on-locators.html
Another explanation from the guy himself here (shorter, might be easier to digest):
https://github.com/zendframework/zend-mvc/issues/89
I am currently also in the process of trying to migrate a ZF2 (2.4.10) project to ZF3 and face the same issue.
I personally agree with the recommendation to explicitly define dependencies of your classes and controllers instead of (over)using getServiceLocator() method, though depending on your code, refactoring lots of code for this purpose might seem to be a PITA.
Alternatively, this can probably help (though, i can't say for sure since i haven't tried this myself):
http://circlical.com/blog/2016/3/9/preparing-for-zend-f

Eloquent (without Laravel) caching implementation

I am using Eloquent without Laravel and I'm wondering if there's a method which can be used (and does not rely on Laravel components) to integrate a caching method which then automatically caches all model queries (caching backend can be variable, say APCu or memcache).
I'm thinking that it should be possible to write a model base class which handles this but I'm not quite sure how I would go about implementing this. Does anybody have any ideas in this direction?
If you want to auto cache your query, you have to override the find(), findOrFail() , where() ... methods
Because of how Eloquent is built you can't simply add a method find() in your custom model class
https://laracasts.com/discuss/channels/eloquent/override-find-method/replies/72028
class MyCacheModel extends \Illuminate\Database\Eloquent\Model
{
// override methods as explained in previous link
// cache the result in redis for how long you want
}
Then in your model instead of extending Eloquent\Model, extends now from your MyCacheModel. With a bit of customization you can set how long queries will be cached and if a model shouldn't be cached then just use the Eloquent\Model.

How can I have my trait extend a class

I understand that by definition, a trait cannot extend a class, however I'm wondering if there's some kind of workaround.
My situation:
I created the package revisionable, which in its first incarnation was a class that you extended from your model which itself extended Laravels base Eloquent class, however over time there were plenty of requests to change this into a trait, so people could use revisionable, and be able to extend their own base class.
Currently, the only that I can think to allow for both an extendable class, and a trait, is to offer both as a whole files, which means I'm repeating the entire code in two files which could easily lead to trouble down the road.
I'm wondering if anybody knows of some solution where I can have one file that is god, and the other file relies on it.
Rules
The existing class cannot use a trait, as existing users of the package on php 5.3 will not have access to traits.
There's absolutely no way to accomplish what you want.
Since Laravel itself (in 4.2) has now abandoned PHP 5.3, it's time to move on too.
Tag a new release that drops the class, add a PHP 5.4 requirement to your composer.josn file, and add this information to your docs.
Anyone still stuck on 5.3 can always just composer require your previous version.
Php 5.3 is a problem.
Back in when it was popular, the programming style was all about include/require files into another files. If you can split your functionality into functions that may be included in trait and in class - it may be a solution. But it depends of the functionality.
Modern way would be decoupling and dependency injections, in other words think units and unittesting.
Problem of a trait as well as the problem of the child-class is that you cannot unittest the pure functionality of what you have done without touching the parent class functionality. You cannot mock parent class, you can only mock injected class, right?
Think modern. Create a class, inject Eloquent object there. And then use this class in traits and some parent class for laravel models.
And forgive Taylor for the fact that you cannot mock the Eloquent. He may be able to fix it in new versions of Laravel. But you'll have to move to PHP7 because it is a requirement for latest laravel releases.

How do I namespace a model in Laravel so as not to clash with an existing class?

In Laravel 4 I want to use a model that represents an Event coming from my database. Thus, in app/models I have my Event model that extends Eloquent.
However, Laravel 4 already has an Event class which is used to manage events within the application lifecycle.
What I want to know is, how can I properly namespace my Event model and access it in a way that will not clash with the existing Event class.
You just need to apply a namespace to it as you normally would. So, for example.
<?php namespace Models;
use Eloquent;
class Event extends Eloquent {
}
You should then correctly setup your composer.json so that it loads your models. You could use classmap or psr-0 for this, depending on whether or not you're following PSR-0 with your directory structure.
I'm pretty sure the models directory is already mapped.
Edit
As mentioned in the comments you must run composer dump-autoload.
As much i have research about using namespaces, because i want to use those inside the PHPDocumentar, its not possible to add twice the namespaces, as laravel already adds those for you, if we understand the basic problem, why we use namespaces
1 - many libraries uses same class name, so we use namespaces to differentiate that.
2 - if you want to use namespaces then you should be out of the scope of the app, means is the vendor folder for you to this kind of stuff.
Enjoy

Categories