-
-
Notifications
You must be signed in to change notification settings - Fork 861
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[8.0] Support for plugin engine methods. #1462
[8.0] Support for plugin engine methods. #1462
Conversation
src/CollectionDataTable.php
Outdated
return is_array($source) || $source instanceof Collection; | ||
} | ||
|
||
public static function create($source) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add the missing docs.
src/DataTableAbstract.php
Outdated
@@ -137,6 +137,28 @@ | |||
protected $config; | |||
|
|||
/** | |||
* Can the DataTable engine be created for these parameters |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add all the missing period on docs.
PR looks great ❤️ . Need some minor changes and I think this is good to go. Will do some actual testing on a project though when I got the chance just to make sure. But I guess the test is sufficient enough to tell that this works :). |
I have added the docs. I actually didnt include them in Collection on purpose because phpdoc should inherit the docs from the Abstract class by default anyway, but I guess this is indeed better as now they list the correct param/return types :) What are your thoughts about the Also, I left in the |
Actually, queryBuilder is a fluent query builder and not eloquent. Maybe we can add another class |
src/QueryDataTable.php
Outdated
@@ -45,6 +45,11 @@ class QueryDataTable extends DataTableAbstract | |||
*/ | |||
protected $limitCallback; | |||
|
|||
public static function canCreate($source) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing docs. Maybe we can use @inheritdoc
? But I usually copy and paste the comments :)
src/EloquentDataTable.php
Outdated
@@ -15,6 +16,11 @@ class EloquentDataTable extends QueryDataTable | |||
*/ | |||
protected $query; | |||
|
|||
public static function canCreate($source) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing doc.
@yajra Sorry for missing those phpdocs in the previous commit, I have added them 😅 I have also added a commit with my proposal for deprecating the QueryDataTable class, hope you dont mind but it was just as easy as first discussing the required changes here. I have also added a test to make sure we still fully support the old datatables config using the deprecated engine. That test can be removed when we really remove the QueryDataTable class. Btw, if you prefer a second PR for that I can rollback that commit but then I have to wait until you accept this PR due to too many files that are changed in both PR's ;) |
src/config/datatables.php
Outdated
@@ -39,19 +39,21 @@ | |||
* This is where you can register your custom dataTables builder. | |||
*/ | |||
'engines' => [ | |||
'eloquent' => \Yajra\DataTables\EloquentDataTable::class, | |||
'query' => \Yajra\DataTables\QueryDataTable::class, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can retain query
engine to prevent breaking change. This way, users with old config won't break?
Also, this would also become an additional feature where we can just use DataTables::query()
for a shorter syntax?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a Deprecated test as well to make sure we still support the old config's. Maybe I missed a use-case in that? See: https://github.com/pimlie/laravel-datatables/blob/feature-support-plugin-engine-methods/tests/Integration/DeprecatedQueryEngineTest.php
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah my mistake, it is not a breaking change but I think it's nice to have query()
engine? Thanks!
I just realized that -- Edit -- $query = User::query(); |
I dont have a strong preference for either Hmm, so I guess that means we only have to deprecate the |
In my opinion, Yes, we deprecate |
…o feature-support-plugin-engine-methods
4d50ac2
to
9563010
Compare
To be more consistent in naming, deprecate queryBuilder direct access method in favor of query
9563010
to
3352114
Compare
Great, I have rolled back the Deprecation commit and added a new one. I also renamed the integration test and added a test for the (now) deprecated queryBuilder method just to be sure :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some minor doc and cs changes and I think this is good to go. Thanks a lot!
src/CollectionDataTable.php
Outdated
* Factory method, create and return an instance for the DataTable engine. | ||
* | ||
* @param array|\Illuminate\Support\Collection $source | ||
* @return \Illuminate\Support\Collection |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the correct return doc here is CollectionDataTable|DataTableAbstract
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe not, the |
indicates that either of those two types can be returned but in this case it always returns a CollectionDataTable (which just happens to be an instance of DataTableAbstract). I actually think you shouldnt use DataTableAbstract as a type anywhere as an abstract class can never be instantiated and its always the parent class you should list. But correct me if I am wrong..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not really sure too. Sometimes, scrutinizer complains on things like this. Using PHPStorm, it will suggest to return both so I often go towards it. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thats probably because it doesnt understand that with the parent::create
we call a method of the abstract class which uses the static
keyword to return an instance of the current class.
The following code will probably trick PHPStorm to get it right:
$datatable = parent::create($source);
/* @var $datatable CollectionDataTable */
return $datatable;
Should I use that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe /* @var $datatable self */
works too btw
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is safe to use CollectionDataTable|DataTableAbstract
. This way, IDE like phpstorm won't complain since it is compatible on the parent class as it returns DataTableAbstract
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes boss, done and done 😄
src/DataTables.php
Outdated
@@ -80,26 +84,35 @@ public function getConfig() | |||
return app('datatables.config'); | |||
} | |||
|
|||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Excess new line?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes :)
Released on 🚀 v8.3.0. ❤️ ❤️ ❤️ Thanks! |
Thank you for merging 👍 Fyi, for my mongodb plugin I have added another method for easy registration of custom engines by adding a serviceprovider to it. In the serviceprovider I merge the available engines dynamically to the |
Oh yeah, that's a good idea. Will update the scout plugin too when I got the chance. It's not yet stable :)... BTW, would you mind if I link any mongodb related issues to your plugin? Doesn't have much knowledge on mongodb as I haven't use it yet personally on any project. TIA. |
Sure no problem! |
Oh my... |
I am confused about the purpose of In my opinion, DataTables singleton may be not needed if there is a static And, for me, if the engines are configurable, why we define |
And I don't think depending upon |
I already mentioned in my 2nd post that the But I dont think depending on That said I agree with you that those methods arent really that necessary, there are already many other ways of instantiating datatable engines of which |
I think the Macroable is only useful for the lazy package/module users. |
So do you have another solution besides just removing the closures for the lazy users? Btw, why do you say 'reduplicate'? |
It was originally inherited from the original package and was retained for familiarity of users migrating to this package.
It was added for facade to work. Or I might be wrong?
It was used on older version of the package and by the buttons plugin. It was retained for backward compatibility. But I guess we can deprecate it and be removed on next major version? |
@pimlie I think this PR made DataTables factory more extendable, but with a complex API. If someone wants to extend an exist engine or add new, he should be careful, as the doc of
Before extending, the users may need to know exactly what is the meaning of this doc line. Commented "reduplicate" means |
@yajra Think about current use Yajra\DataTables\DataTables;
function datatables($source = null)
{
if ($source) {
return DataTables::make($source);
}
return new DataTables;
} If someone wants to override function datatables($source = null)
{
if ($source) {
return app('datatables')->make($source);
}
return app('datatables');
} Since DataTables is a singleton, letting |
Does the following make sense? Configuration 'engines' => [
'eloquent' => Yajra\DataTables\EloquentDataTable::class,
'query' => Yajra\DataTables\QueryDataTable::class,
'collection' => Yajra\DataTables\CollectionDataTable::class,
],
'builders' => [
'eloquent' => [
Illuminate\Database\Eloquent\Relations\Relation::class,
Illuminate\Database\Eloquent\Builder::class,
],
'query' => Illuminate\Database\Query\Builder::class,
'collection' => Illuminate\Support\Collection::class,
], I exchange key and value for DataTables namespace Yajra\DataTables;
class DataTables
{
public function make($source)
{
foreach (config('datatables.builders') as $engine => $classes) {
foreach ((array) $classes as $class) {
if ($source instanceof $class) {
return $this->createDataTable($engine, func_get_args());
}
}
}
throw new \Exception('No available engine for ' . get_class($source));
}
protected function createDataTable($engine, $parameters)
{
$class = config('datatables.engines.'.$engine);
if (! $class) {
throw new \InvalidArgumentException("DataTable engine {$engine} does not exist.");
}
// If we want to support dependency injection for DataTable classes
// return app()->make($class, $parameters);
return (new \ReflectionClass($class))->newInstanceArgs($parameters);
}
public function __call($engine, $parameters)
{
return $this->createDataTable($engine, $parameters);
}
} If we would like to add I am not sure whether we need to support variable parameters for helper.php if (! function_exists('datatables')) {
function datatables($source = null)
{
return is_null($source)
? app('datatables')
: call_user_func_array([app('datatables'), 'make'], func_get_args());
}
} In this PR, Usage datatables($query);
datatables()->eloquent($query);
\DataTables::eloquent($query); Example of handling mixed source class CollectionDataTable extends DataTableAbstract
{
public function __construct($source)
{
$this->collection = $source instanceof Collection
? $source : new Collection($source);
// ...
}
} Extending: To override built-in engines or add new, just change the config file: 'engines' => [
'eloquent' => App\DataTables\EloquentDataTable::class,
'mongodb' => App\DataTables\MongodbDataTable::class,
// ...
], If you have different engines for the sources extended the same base class, just take note of the order in 'builders' => [
'mongodb' => [
Subclass\Of\Illuminate\Database\Eloquent\Relations\Relation::class,
Illuminate\Database\Eloquent\Builder::class,
// ...
],
'eloquent' => [
Illuminate\Database\Eloquent\Relations\Relation::class,
Illuminate\Database\Eloquent\Builder::class,
],
// ...
], In brief, the DataTables factory only depends on the configuration, no matter this package, user application, or other plugin packages. |
@ElfSundae maybe you can submit another PR and we can discuss this there further. Your proposal makes sense too and I agree with you with regard to |
OK |
Although I have no issue with most of your suggestions, using But what I wanted to do with this PR is to make the configuration easier. Why do we always need to configure a mapping between builder classes and engines when probably for most of the users the default builders provided by an engine are ok? Its only adding another point where you can introduce bugs/mistakes. Also I am not a big fan of deliberate type switching if you can avoid it. Although php is loosely typed I think it can be confusing when the builders config can have both array as a string/class reference elements. With the implementation in this PR you can already do what you want with regards to registering custom builders to engines. The only issue what this PR didnt address where those engine specific methods in DataTables. I think your suggestion for using -- edit -- |
Oh, and I indeed used So if you really want we could remove the |
Thinking about it, actually I would even prefer to go a step further and also remove the default engine list in the configuration as well. Just put them hard coded in --edit-- |
Let's discuss in #1488 |
As discussed in #1294
I have implemented more dynamic/flexibel methods for creating DataTable engines instances, the changes are:
DataTables.php
boot
method inDataTablesServiceProvider
to add macro's for all engine names listed inconfig/datatables.php
. Engine names are converted to camelCase, so if you list an engine asmongodb-query
the macro will be namedmongodbQuery
.canCreate
andcreate
methods inDataTableAbstract
.With the
canCreate
method a DataTableEngine can indicate whether they can be create with the supplied parameters (see Collection for the most interesting use-case). Thecreate
method then returns an instance of the DataTable engine. With these 2 methods DataTable Engine plugins have full control over how they should be used. See the CollectionEngine again which required a special treatment inDataTables.php
(with the conversion from array to Collection) but is now fully self sufficient ;)Due to the
canCreate
method theconfig.datatables.builders
option has become redundant, see the new implementation ofDataTables::make
. Therefore I would like to propose to comment out the builder options inconfig/datatables.php
by default and mark that as a 'advanced configuration' option. That way advanced users can still override the builder to engine mapping, but if eg an Engine would split support for one of its supported Builders to a different class the bulk of the users are not affected.