updated-packages
This commit is contained in:
10
vendor/yajra/laravel-datatables-oracle/.styleci.yml
vendored
Normal file
10
vendor/yajra/laravel-datatables-oracle/.styleci.yml
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
preset: laravel
|
||||
|
||||
enabled:
|
||||
- align_double_arrow
|
||||
- align_equals
|
||||
- no_useless_else
|
||||
|
||||
disabled:
|
||||
- concat_without_spaces
|
||||
- unalign_equals
|
1017
vendor/yajra/laravel-datatables-oracle/CHANGELOG.md
vendored
1017
vendor/yajra/laravel-datatables-oracle/CHANGELOG.md
vendored
File diff suppressed because it is too large
Load Diff
22
vendor/yajra/laravel-datatables-oracle/CONDUCT.md
vendored
Normal file
22
vendor/yajra/laravel-datatables-oracle/CONDUCT.md
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
# Contributor Code of Conduct
|
||||
|
||||
As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
|
||||
|
||||
We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or nationality.
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery
|
||||
* Personal attacks
|
||||
* Trolling or insulting/derogatory comments
|
||||
* Public or private harassment
|
||||
* Publishing other's private information, such as physical or electronic addresses, without explicit permission
|
||||
* Other unethical or unprofessional conduct.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. By adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently applying these principles to every aspect of managing this project. Project maintainers who do not follow or enforce the Code of Conduct may be permanently removed from the project team.
|
||||
|
||||
This code of conduct applies both within project spaces and in public spaces when an individual is representing the project or its community in a direct capacity. Personal views, beliefs and values of individuals do not necessarily reflect those of the organisation or affiliated individuals and organisations.
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.2.0, available at [http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/)
|
@@ -1,6 +1,6 @@
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2013-2016 Arjay Angeles <aqangeles@gmail.com>
|
||||
Copyright (c) 2013-2019 Arjay Angeles <aqangeles@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
|
116
vendor/yajra/laravel-datatables-oracle/README.md
vendored
116
vendor/yajra/laravel-datatables-oracle/README.md
vendored
@@ -1,70 +1,107 @@
|
||||
# jQuery DataTables API for Laravel 4|5
|
||||
# jQuery DataTables API for Laravel 4|5|6
|
||||
|
||||
[](https://gitter.im/yajra/laravel-datatables?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
[](https://www.paypal.me/yajra)
|
||||
[](https://www.patreon.com/bePatron?u=4521203)
|
||||
|
||||
[](http://laravel.com)
|
||||
[](https://packagist.org/packages/yajra/laravel-datatables-oracle)
|
||||
[](http://laravel.com)
|
||||
[](https://packagist.org/packages/yajra/laravel-datatables-oracle)
|
||||
[](https://packagist.org/packages/yajra/laravel-datatables-oracle)
|
||||
[](https://travis-ci.org/yajra/laravel-datatables)
|
||||
[](https://scrutinizer-ci.com/g/yajra/laravel-datatables/?branch=master)
|
||||
[](https://packagist.org/packages/yajra/laravel-datatables-oracle)
|
||||
[](https://packagist.org/packages/yajra/laravel-datatables-oracle)
|
||||
[](https://packagist.org/packages/yajra/laravel-datatables-oracle)
|
||||
[](https://packagist.org/packages/yajra/laravel-datatables-oracle)
|
||||
|
||||
This package is created to handle [server-side](https://www.datatables.net/manual/server-side) works of [DataTables](http://datatables.net) jQuery Plugin via [AJAX option](https://datatables.net/reference/option/ajax) by using Eloquent ORM, Fluent Query Builder or Collection.
|
||||
|
||||
```php
|
||||
use Yajra\Datatables\Facades\Datatables;
|
||||
return datatables()->of(User::query())->toJson();
|
||||
return datatables()->of(DB::table('users'))->toJson();
|
||||
return datatables()->of(User::all())->toJson();
|
||||
|
||||
// Using Eloquent
|
||||
return Datatables::eloquent(User::query())->make(true);
|
||||
return datatables()->eloquent(User::query())->toJson();
|
||||
return datatables()->query(DB::table('users'))->toJson();
|
||||
return datatables()->collection(User::all())->toJson();
|
||||
|
||||
// Using Query Builder
|
||||
return Datatables::queryBuilder(DB::table('users'))->make(true);
|
||||
|
||||
// Using Collection
|
||||
return Datatables::collection(User::all())->make(true);
|
||||
|
||||
// Using the Engine Factory
|
||||
return Datatables::of(User::query())->make(true);
|
||||
return Datatables::of(DB::table('users'))->make(true);
|
||||
return Datatables::of(User::all())->make(true);
|
||||
return datatables(User::query())->toJson();
|
||||
return datatables(DB::table('users'))->toJson();
|
||||
return datatables(User::all())->toJson();
|
||||
```
|
||||
|
||||
## Requirements
|
||||
- [PHP 5.5.9 or later](http://php.net/)
|
||||
- [Laravel 5.0 or later](https://github.com/laravel/framework)
|
||||
- [DataTables jQuery Plugin](http://datatables.net/) **Version 1.10.xx**
|
||||
- [PHP >= 7.0](http://php.net/)
|
||||
- [Laravel 5.x|6.x](https://github.com/laravel/framework)
|
||||
- [jQuery DataTables v1.10.x](http://datatables.net/)
|
||||
|
||||
## Documentations
|
||||
- You will find user friendly and updated documentation in the wiki here: [Laravel Datatables Wiki](https://github.com/yajra/laravel-datatables/wiki)
|
||||
- You will find the API Documentation here: [Laravel Datatables API](http://yajra.github.io/laravel-datatables/api/)
|
||||
- [Demo Application](http://datatables.yajrabox.com) is available for artisan's reference.
|
||||
|
||||
- [Github Docs](https://github.com/yajra/laravel-datatables-docs)
|
||||
- [Laravel DataTables Quick Starter](https://yajrabox.com/docs/laravel-datatables/master/quick-starter)
|
||||
- [Laravel DataTables Documentation](https://yajrabox.com/docs/laravel-datatables)
|
||||
- [Laravel 5.0 - 5.3 Demo Application](https://datatables.yajrabox.com)
|
||||
|
||||
**NOTE: Documentation links below are currently offline.**
|
||||
|
||||
- [Laravel 5.4 Demo Application](http://dt54.yajrabox.com)
|
||||
|
||||
## Laravel Version Compatibility
|
||||
|
||||
Laravel | Package
|
||||
:---------|:----------
|
||||
4.2.x | 3.x
|
||||
5.0.x | 6.x
|
||||
5.1.x | 6.x
|
||||
5.2.x | 6.x
|
||||
5.3.x | 6.x
|
||||
5.4.x | 7.x, 8.x
|
||||
5.5.x | 8.x
|
||||
5.6.x | 8.x
|
||||
5.7.x | 8.x
|
||||
5.8.x | 9.x
|
||||
6.x.x | 9.x
|
||||
7.x.x | 9.x
|
||||
|
||||
## DataTables 8.x Upgrade Guide
|
||||
There are breaking changes since DataTables v8.x.
|
||||
If you are upgrading from v7.x to v8.x, please see [upgrade guide](https://yajrabox.com/docs/laravel-datatables/master/upgrade).
|
||||
|
||||
## Quick Installation
|
||||
`composer require yajra/laravel-datatables-oracle:~6.0`
|
||||
```bash
|
||||
$ composer require yajra/laravel-datatables-oracle:"~9.0"
|
||||
```
|
||||
|
||||
#### Service Provider
|
||||
`Yajra\Datatables\DatatablesServiceProvider::class`
|
||||
#### Service Provider & Facade (Optional on Laravel 5.5)
|
||||
Register provider and facade on your `config/app.php` file.
|
||||
```php
|
||||
'providers' => [
|
||||
...,
|
||||
Yajra\DataTables\DataTablesServiceProvider::class,
|
||||
]
|
||||
|
||||
#### Facade
|
||||
`Datatables` facade is automatically registered as an alias for `Yajra\Datatables\Facades\Datatables` class.
|
||||
'aliases' => [
|
||||
...,
|
||||
'DataTables' => Yajra\DataTables\Facades\DataTables::class,
|
||||
]
|
||||
```
|
||||
|
||||
#### Configuration and Assets
|
||||
`$ php artisan vendor:publish --tag=datatables`
|
||||
#### Configuration (Optional)
|
||||
```bash
|
||||
$ php artisan vendor:publish --provider="Yajra\DataTables\DataTablesServiceProvider"
|
||||
```
|
||||
|
||||
And that's it! Start building out some awesome DataTables!
|
||||
|
||||
## Upgrading from v5.x to v6.x
|
||||
- Change all occurrences of `yajra\Datatables` to `Yajra\Datatables`. (Use Sublime's find and replace all for faster update).
|
||||
- Remove `Datatables` facade registration.
|
||||
- Temporarily comment out `Yajra\Datatables\DatatablesServiceProvider`.
|
||||
- Update package version on your composer.json and use `yajra/laravel-datatables-oracle: ~6.0`
|
||||
- Uncomment the provider `Yajra\Datatables\DatatablesServiceProvider`.
|
||||
|
||||
## Debugging Mode
|
||||
To enable debugging mode, just set `APP_DEBUG=true` and the package will include the queries and inputs used when processing the table.
|
||||
|
||||
**IMPORTANT:** Please make sure that APP_DEBUG is set to false when your app is on production.
|
||||
|
||||
## PHP ARTISAN SERVE BUG
|
||||
Please avoid using `php artisan serve` when developing with the package.
|
||||
There are known bugs when using this where Laravel randomly returns a redirect and 401 (Unauthorized) if the route requires authentication and a 404 NotFoundHttpException on valid routes.
|
||||
|
||||
It is advised to use [Homestead](https://laravel.com/docs/5.4/homestead) or [Valet](https://laravel.com/docs/5.4/valet) when working with the package.
|
||||
|
||||
## Contributing
|
||||
|
||||
Please see [CONTRIBUTING](https://github.com/yajra/laravel-datatables/blob/master/.github/CONTRIBUTING.md) for details.
|
||||
@@ -82,6 +119,3 @@ If you discover any security related issues, please email [aqangeles@gmail.com](
|
||||
## License
|
||||
|
||||
The MIT License (MIT). Please see [License File](https://github.com/yajra/laravel-datatables/blob/master/LICENSE.md) for more information.
|
||||
|
||||
## Buy me a beer
|
||||
<a href='https://pledgie.com/campaigns/29515'><img alt='Click here to lend your support to: Laravel Datatables and make a donation at pledgie.com !' src='https://pledgie.com/campaigns/29515.png?skin_name=chrome' border='0' ></a>
|
||||
|
12
vendor/yajra/laravel-datatables-oracle/UPGRADE.md
vendored
Normal file
12
vendor/yajra/laravel-datatables-oracle/UPGRADE.md
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
## Upgrading from v6.x to v7.x
|
||||
- composer require yajra/laravel-datatables-oracle
|
||||
- composer require yajra/laravel-datatables-buttons
|
||||
- php artisan vendor:publish --tag=datatables --force
|
||||
- php artisan vendor:publish --tag=datatables-buttons --force
|
||||
|
||||
## Upgrading from v5.x to v6.x
|
||||
- Change all occurrences of `yajra\Datatables` to `Yajra\Datatables`. (Use Sublime's find and replace all for faster update).
|
||||
- Remove `Datatables` facade registration.
|
||||
- Temporarily comment out `Yajra\Datatables\DatatablesServiceProvider`.
|
||||
- Update package version on your composer.json and use `yajra/laravel-datatables-oracle: ~6.0`
|
||||
- Uncomment the provider `Yajra\Datatables\DatatablesServiceProvider`.
|
@@ -1,37 +1,67 @@
|
||||
{
|
||||
"name": "yajra/laravel-datatables-oracle",
|
||||
"description": "jQuery DataTables API for Laravel 4|5",
|
||||
"keywords" : ["laravel4","laravel5","laravel","datatables","datatable","datatables jquery plugin"],
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Arjay Angeles",
|
||||
"email": "aqangeles@gmail.com"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.5.9",
|
||||
"illuminate/support": "~5.0",
|
||||
"illuminate/database": "~5.0",
|
||||
"illuminate/view": "~5.0",
|
||||
"illuminate/http": "~5.0",
|
||||
"illuminate/filesystem": "~5.0",
|
||||
"league/fractal": "~0.12",
|
||||
"laravelcollective/html": "~5.0",
|
||||
"maatwebsite/excel": "^2.0",
|
||||
"dompdf/dompdf": "^0.6.1"
|
||||
"name": "yajra/laravel-datatables-oracle",
|
||||
"description": "jQuery DataTables API for Laravel 4|5",
|
||||
"keywords": [
|
||||
"laravel",
|
||||
"dataTables",
|
||||
"jquery"
|
||||
],
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Arjay Angeles",
|
||||
"email": "aqangeles@gmail.com"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^7.1.3",
|
||||
"illuminate/database": "5.8.*|^6|^7",
|
||||
"illuminate/filesystem": "5.8.*|^6|^7",
|
||||
"illuminate/http": "5.8.*|^6|^7",
|
||||
"illuminate/support": "5.8.*|^6|^7",
|
||||
"illuminate/view": "5.8.*|^6|^7"
|
||||
},
|
||||
"require-dev": {
|
||||
"orchestra/testbench": "^3.8"
|
||||
},
|
||||
"suggest": {
|
||||
"yajra/laravel-datatables-buttons": "Plugin for server-side exporting of dataTables.",
|
||||
"yajra/laravel-datatables-html": "Plugin for server-side HTML builder of dataTables.",
|
||||
"yajra/laravel-datatables-fractal": "Plugin for server-side response using Fractal.",
|
||||
"yajra/laravel-datatables-editor": "Plugin to use DataTables Editor (requires a license)."
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Yajra\\DataTables\\": "src/"
|
||||
},
|
||||
"require-dev": {
|
||||
"mockery/mockery": "~0.9",
|
||||
"phpunit/phpunit": "~4.0"
|
||||
"files": [
|
||||
"src/helper.php"
|
||||
]
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Yajra\\DataTables\\Tests\\": "tests/"
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "9.0-dev"
|
||||
},
|
||||
"suggest": {
|
||||
"barryvdh/laravel-snappy": "Allows exporting of dataTable to PDF using the print view."
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Yajra\\Datatables\\": "src/"
|
||||
}
|
||||
},
|
||||
"minimum-stability": "stable"
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Yajra\\DataTables\\DataTablesServiceProvider"
|
||||
],
|
||||
"aliases": {
|
||||
"DataTables": "Yajra\\DataTables\\Facades\\DataTables"
|
||||
}
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"sort-packages": true
|
||||
},
|
||||
"scripts": {
|
||||
"test": "vendor/bin/phpunit"
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"prefer-stable": true
|
||||
}
|
||||
|
17
vendor/yajra/laravel-datatables-oracle/phpunit.xml.dist
vendored
Normal file
17
vendor/yajra/laravel-datatables-oracle/phpunit.xml.dist
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit backupGlobals="false"
|
||||
backupStaticAttributes="false"
|
||||
bootstrap="vendor/autoload.php"
|
||||
colors="true"
|
||||
convertErrorsToExceptions="true"
|
||||
convertNoticesToExceptions="true"
|
||||
convertWarningsToExceptions="true"
|
||||
processIsolation="false"
|
||||
stopOnFailure="false"
|
||||
>
|
||||
<testsuites>
|
||||
<testsuite name="Package Test Suite">
|
||||
<directory suffix=".php">./tests/</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
</phpunit>
|
63
vendor/yajra/laravel-datatables-oracle/src/ApiResourceDataTable.php
vendored
Normal file
63
vendor/yajra/laravel-datatables-oracle/src/ApiResourceDataTable.php
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\DataTables;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
|
||||
|
||||
class ApiResourceDataTable extends CollectionDataTable
|
||||
{
|
||||
/**
|
||||
* Collection object.
|
||||
*
|
||||
* @var \Illuminate\Http\Resources\Json\AnonymousResourceCollection
|
||||
*/
|
||||
public $collection;
|
||||
|
||||
/**
|
||||
* Collection object.
|
||||
*
|
||||
* @var \Illuminate\Http\Resources\Json\AnonymousResourceCollection
|
||||
*/
|
||||
public $original;
|
||||
|
||||
/**
|
||||
* Can the DataTable engine be created with these parameters.
|
||||
*
|
||||
* @param mixed $source
|
||||
* @return bool
|
||||
*/
|
||||
public static function canCreate($source)
|
||||
{
|
||||
return $source instanceof AnonymousResourceCollection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method, create and return an instance for the DataTable engine.
|
||||
*
|
||||
* @param \Illuminate\Http\Resources\Json\AnonymousResourceCollection $source
|
||||
* @return ApiResourceDataTable|DataTableAbstract
|
||||
*/
|
||||
public static function create($source)
|
||||
{
|
||||
return parent::create($source);
|
||||
}
|
||||
|
||||
/**
|
||||
* CollectionEngine constructor.
|
||||
*
|
||||
* @param \Illuminate\Http\Resources\Json\AnonymousResourceCollection $collection
|
||||
*/
|
||||
public function __construct(AnonymousResourceCollection $collection)
|
||||
{
|
||||
$this->request = app('datatables.request');
|
||||
$this->config = app('datatables.config');
|
||||
$this->collection = collect($collection->toArray($this->request));
|
||||
$this->original = $collection;
|
||||
$this->columns = array_keys($this->serialize(collect($collection->toArray($this->request))->first()));
|
||||
if ($collection->resource instanceof LengthAwarePaginator) {
|
||||
$this->isFilterApplied = true;
|
||||
}
|
||||
}
|
||||
}
|
338
vendor/yajra/laravel-datatables-oracle/src/CollectionDataTable.php
vendored
Normal file
338
vendor/yajra/laravel-datatables-oracle/src/CollectionDataTable.php
vendored
Normal file
@@ -0,0 +1,338 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\DataTables;
|
||||
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
|
||||
class CollectionDataTable extends DataTableAbstract
|
||||
{
|
||||
/**
|
||||
* Collection object.
|
||||
*
|
||||
* @var \Illuminate\Support\Collection
|
||||
*/
|
||||
public $collection;
|
||||
|
||||
/**
|
||||
* Collection object.
|
||||
*
|
||||
* @var \Illuminate\Support\Collection
|
||||
*/
|
||||
public $original;
|
||||
|
||||
/**
|
||||
* The offset of the first record in the full dataset.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $offset = 0;
|
||||
|
||||
/**
|
||||
* Can the DataTable engine be created with these parameters.
|
||||
*
|
||||
* @param mixed $source
|
||||
* @return bool
|
||||
*/
|
||||
public static function canCreate($source)
|
||||
{
|
||||
return is_array($source) || $source instanceof Collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method, create and return an instance for the DataTable engine.
|
||||
*
|
||||
* @param array|\Illuminate\Support\Collection $source
|
||||
* @return CollectionDataTable|DataTableAbstract
|
||||
*/
|
||||
public static function create($source)
|
||||
{
|
||||
if (is_array($source)) {
|
||||
$source = new Collection($source);
|
||||
}
|
||||
|
||||
return parent::create($source);
|
||||
}
|
||||
|
||||
/**
|
||||
* CollectionEngine constructor.
|
||||
*
|
||||
* @param \Illuminate\Support\Collection $collection
|
||||
*/
|
||||
public function __construct(Collection $collection)
|
||||
{
|
||||
$this->request = app('datatables.request');
|
||||
$this->config = app('datatables.config');
|
||||
$this->collection = $collection;
|
||||
$this->original = $collection;
|
||||
$this->columns = array_keys($this->serialize($collection->first()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize collection.
|
||||
*
|
||||
* @param mixed $collection
|
||||
* @return mixed|null
|
||||
*/
|
||||
protected function serialize($collection)
|
||||
{
|
||||
return $collection instanceof Arrayable ? $collection->toArray() : (array) $collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Count results.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return $this->collection->count() > $this->totalRecords ? $this->totalRecords : $this->collection->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform column search.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function columnSearch()
|
||||
{
|
||||
$columns = $this->request->get('columns', []);
|
||||
for ($i = 0, $c = count($columns); $i < $c; $i++) {
|
||||
$column = $this->getColumnName($i);
|
||||
|
||||
if (! $this->request->isColumnSearchable($i) || $this->isBlacklisted($column)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->isFilterApplied = true;
|
||||
|
||||
$regex = $this->request->isRegex($i);
|
||||
$keyword = $this->request->columnKeyword($i);
|
||||
|
||||
$this->collection = $this->collection->filter(
|
||||
function ($row) use ($column, $keyword, $regex) {
|
||||
$data = $this->serialize($row);
|
||||
|
||||
$value = Arr::get($data, $column);
|
||||
|
||||
if ($this->config->isCaseInsensitive()) {
|
||||
if ($regex) {
|
||||
return preg_match('/' . $keyword . '/i', $value) == 1;
|
||||
}
|
||||
|
||||
return strpos(Str::lower($value), Str::lower($keyword)) !== false;
|
||||
}
|
||||
|
||||
if ($regex) {
|
||||
return preg_match('/' . $keyword . '/', $value) == 1;
|
||||
}
|
||||
|
||||
return strpos($value, $keyword) !== false;
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform pagination.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function paging()
|
||||
{
|
||||
$this->collection = $this->collection->slice(
|
||||
$this->request->input('start') - $this->offset,
|
||||
(int) $this->request->input('length') > 0 ? $this->request->input('length') : 10
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Organizes works.
|
||||
*
|
||||
* @param bool $mDataSupport
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function make($mDataSupport = true)
|
||||
{
|
||||
try {
|
||||
$this->totalRecords = $this->totalCount();
|
||||
|
||||
if ($this->totalRecords) {
|
||||
$results = $this->results();
|
||||
$processed = $this->processResults($results, $mDataSupport);
|
||||
$output = $this->transform($results, $processed);
|
||||
|
||||
$this->collection = collect($output);
|
||||
$this->ordering();
|
||||
$this->filterRecords();
|
||||
$this->paginate();
|
||||
|
||||
$this->revertIndexColumn($mDataSupport);
|
||||
}
|
||||
|
||||
return $this->render($this->collection->values()->all());
|
||||
} catch (\Exception $exception) {
|
||||
return $this->errorResponse($exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Count total items.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function totalCount()
|
||||
{
|
||||
return $this->totalRecords ? $this->totalRecords : $this->collection->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get results.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function results()
|
||||
{
|
||||
return $this->collection->all();
|
||||
}
|
||||
|
||||
/**
|
||||
* Revert transformed DT_RowIndex back to it's original values.
|
||||
*
|
||||
* @param bool $mDataSupport
|
||||
*/
|
||||
private function revertIndexColumn($mDataSupport)
|
||||
{
|
||||
if ($this->columnDef['index']) {
|
||||
$index = $mDataSupport ? config('datatables.index_column', 'DT_RowIndex') : 0;
|
||||
$start = (int) $this->request->input('start');
|
||||
$this->collection->transform(function ($data) use ($index, &$start) {
|
||||
$data[$index] = ++$start;
|
||||
|
||||
return $data;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform global search for the given keyword.
|
||||
*
|
||||
* @param string $keyword
|
||||
*/
|
||||
protected function globalSearch($keyword)
|
||||
{
|
||||
$keyword = $this->config->isCaseInsensitive() ? Str::lower($keyword) : $keyword;
|
||||
|
||||
$this->collection = $this->collection->filter(function ($row) use ($keyword) {
|
||||
$this->isFilterApplied = true;
|
||||
|
||||
$data = $this->serialize($row);
|
||||
foreach ($this->request->searchableColumnIndex() as $index) {
|
||||
$column = $this->getColumnName($index);
|
||||
$value = Arr::get($data, $column);
|
||||
if (! $value || is_array($value)) {
|
||||
if (! is_numeric($value)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$value = (string) $value;
|
||||
}
|
||||
|
||||
$value = $this->config->isCaseInsensitive() ? Str::lower($value) : $value;
|
||||
if (Str::contains($value, $keyword)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform default query orderBy clause.
|
||||
*/
|
||||
protected function defaultOrdering()
|
||||
{
|
||||
$criteria = $this->request->orderableColumns();
|
||||
if (! empty($criteria)) {
|
||||
$sorter = $this->getSorter($criteria);
|
||||
|
||||
$this->collection = $this->collection
|
||||
->map(function ($data) {
|
||||
return Arr::dot($data);
|
||||
})
|
||||
->sort($sorter)
|
||||
->map(function ($data) {
|
||||
foreach ($data as $key => $value) {
|
||||
unset($data[$key]);
|
||||
Arr::set($data, $key, $value);
|
||||
}
|
||||
|
||||
return $data;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get array sorter closure.
|
||||
*
|
||||
* @param array $criteria
|
||||
* @return \Closure
|
||||
*/
|
||||
protected function getSorter(array $criteria)
|
||||
{
|
||||
$sorter = function ($a, $b) use ($criteria) {
|
||||
foreach ($criteria as $orderable) {
|
||||
$column = $this->getColumnName($orderable['column']);
|
||||
$direction = $orderable['direction'];
|
||||
if ($direction === 'desc') {
|
||||
$first = $b;
|
||||
$second = $a;
|
||||
} else {
|
||||
$first = $a;
|
||||
$second = $b;
|
||||
}
|
||||
if ($this->config->isCaseInsensitive()) {
|
||||
$cmp = strnatcasecmp($first[$column], $second[$column]);
|
||||
} else {
|
||||
$cmp = strnatcmp($first[$column], $second[$column]);
|
||||
}
|
||||
if ($cmp != 0) {
|
||||
return $cmp;
|
||||
}
|
||||
}
|
||||
|
||||
// all elements were equal
|
||||
return 0;
|
||||
};
|
||||
|
||||
return $sorter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve callback parameter instance.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
protected function resolveCallbackParameter()
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the offset of the first item of the collection with respect to
|
||||
* the FULL dataset the collection was sliced from. It effectively allows the
|
||||
* collection to be "pre-sliced".
|
||||
*
|
||||
* @param int $offset
|
||||
* @return $this
|
||||
*/
|
||||
public function setOffset(int $offset)
|
||||
{
|
||||
$this->offset = $offset;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
@@ -1,14 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\Datatables\Contracts;
|
||||
namespace Yajra\DataTables\Contracts;
|
||||
|
||||
/**
|
||||
* Interface DataTableEngineContract
|
||||
*
|
||||
* @package Yajra\Datatables\Contracts
|
||||
* @author Arjay Angeles <aqangeles@gmail.com>
|
||||
*/
|
||||
interface DataTableEngineContract
|
||||
interface DataTable
|
||||
{
|
||||
/**
|
||||
* Get results.
|
||||
@@ -20,14 +14,14 @@ interface DataTableEngineContract
|
||||
/**
|
||||
* Count results.
|
||||
*
|
||||
* @return integer
|
||||
* @return int
|
||||
*/
|
||||
public function count();
|
||||
|
||||
/**
|
||||
* Count total items.
|
||||
*
|
||||
* @return integer
|
||||
* @return int
|
||||
*/
|
||||
public function totalCount();
|
||||
|
||||
@@ -35,11 +29,11 @@ interface DataTableEngineContract
|
||||
* Set auto filter off and run your own filter.
|
||||
* Overrides global search.
|
||||
*
|
||||
* @param \Closure $callback
|
||||
* @param bool $globalSearch
|
||||
* @param callable $callback
|
||||
* @param bool $globalSearch
|
||||
* @return $this
|
||||
*/
|
||||
public function filter(\Closure $callback, $globalSearch = false);
|
||||
public function filter(callable $callback, $globalSearch = false);
|
||||
|
||||
/**
|
||||
* Perform global search.
|
||||
@@ -73,8 +67,7 @@ interface DataTableEngineContract
|
||||
* Organizes works.
|
||||
*
|
||||
* @param bool $mDataSupport
|
||||
* @param bool $orderFirst
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function make($mDataSupport = false, $orderFirst = false);
|
||||
public function make($mDataSupport = true);
|
||||
}
|
@@ -1,40 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\Datatables\Contracts;
|
||||
|
||||
/**
|
||||
* Interface DataTableButtonsContract.
|
||||
*
|
||||
* @package Yajra\Datatables\Contracts
|
||||
* @author Arjay Angeles <aqangeles@gmail.com>
|
||||
*/
|
||||
interface DataTableButtonsContract
|
||||
{
|
||||
/**
|
||||
* Export to excel file.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function excel();
|
||||
|
||||
/**
|
||||
* Export to CSV file.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function csv();
|
||||
|
||||
/**
|
||||
* Export to PDF file.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function pdf();
|
||||
|
||||
/**
|
||||
* Display printer friendly view.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function printPreview();
|
||||
}
|
@@ -1,47 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\Datatables\Contracts;
|
||||
|
||||
/**
|
||||
* Interface DataTableContract
|
||||
*
|
||||
* @package Yajra\Datatables\Contracts
|
||||
* @author Arjay Angeles <aqangeles@gmail.com>
|
||||
*/
|
||||
interface DataTableContract
|
||||
{
|
||||
/**
|
||||
* Render view.
|
||||
*
|
||||
* @param $view
|
||||
* @param array $data
|
||||
* @param array $mergeData
|
||||
* @return \Illuminate\Http\JsonResponse|\Illuminate\View\View
|
||||
*/
|
||||
public function render($view, $data = [], $mergeData = []);
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function ajax();
|
||||
|
||||
/**
|
||||
* @return \Yajra\Datatables\Html\Builder
|
||||
*/
|
||||
public function html();
|
||||
|
||||
/**
|
||||
* @return \Yajra\Datatables\Html\Builder
|
||||
*/
|
||||
public function builder();
|
||||
|
||||
/**
|
||||
* @return \Yajra\Datatables\Request
|
||||
*/
|
||||
public function request();
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Query\Builder|\Illuminate\Support\Collection
|
||||
*/
|
||||
public function query();
|
||||
}
|
@@ -1,20 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\Datatables\Contracts;
|
||||
|
||||
/**
|
||||
* Interface DataTableScopeContract.
|
||||
*
|
||||
* @package Yajra\Datatables\Contracts
|
||||
* @author Arjay Angeles <aqangeles@gmail.com>
|
||||
*/
|
||||
interface DataTableScopeContract
|
||||
{
|
||||
/**
|
||||
* Apply a query scope.
|
||||
*
|
||||
* @param \Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder $query
|
||||
* @return mixed
|
||||
*/
|
||||
public function apply($query);
|
||||
}
|
927
vendor/yajra/laravel-datatables-oracle/src/DataTableAbstract.php
vendored
Normal file
927
vendor/yajra/laravel-datatables-oracle/src/DataTableAbstract.php
vendored
Normal file
@@ -0,0 +1,927 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\DataTables;
|
||||
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Str;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Yajra\DataTables\Utilities\Helper;
|
||||
use Illuminate\Support\Traits\Macroable;
|
||||
use Yajra\DataTables\Contracts\DataTable;
|
||||
use Illuminate\Contracts\Support\Jsonable;
|
||||
use Yajra\DataTables\Exceptions\Exception;
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
use Yajra\DataTables\Processors\DataProcessor;
|
||||
|
||||
/**
|
||||
* @method DataTableAbstract setTransformer($transformer)
|
||||
* @method DataTableAbstract setSerializer($transformer)
|
||||
* @property mixed transformer
|
||||
* @property mixed serializer
|
||||
* @see https://github.com/yajra/laravel-datatables-fractal for transformer related methods.
|
||||
*/
|
||||
abstract class DataTableAbstract implements DataTable, Arrayable, Jsonable
|
||||
{
|
||||
use Macroable;
|
||||
|
||||
/**
|
||||
* DataTables Request object.
|
||||
*
|
||||
* @var \Yajra\DataTables\Utilities\Request
|
||||
*/
|
||||
public $request;
|
||||
|
||||
/**
|
||||
* @var \Psr\Log\LoggerInterface
|
||||
*/
|
||||
protected $logger;
|
||||
|
||||
/**
|
||||
* Array of result columns/fields.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $columns = [];
|
||||
|
||||
/**
|
||||
* DT columns definitions container (add/edit/remove/filter/order/escape).
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $columnDef = [
|
||||
'index' => false,
|
||||
'append' => [],
|
||||
'edit' => [],
|
||||
'filter' => [],
|
||||
'order' => [],
|
||||
'only' => null,
|
||||
'hidden' => [],
|
||||
'visible' => [],
|
||||
];
|
||||
|
||||
/**
|
||||
* Extra/Added columns.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $extraColumns = [];
|
||||
|
||||
/**
|
||||
* Total records.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $totalRecords = 0;
|
||||
|
||||
/**
|
||||
* Total filtered records.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $filteredRecords = 0;
|
||||
|
||||
/**
|
||||
* Auto-filter flag.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $autoFilter = true;
|
||||
|
||||
/**
|
||||
* Callback to override global search.
|
||||
*
|
||||
* @var callable
|
||||
*/
|
||||
protected $filterCallback;
|
||||
|
||||
/**
|
||||
* DT row templates container.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $templates = [
|
||||
'DT_RowId' => '',
|
||||
'DT_RowClass' => '',
|
||||
'DT_RowData' => [],
|
||||
'DT_RowAttr' => [],
|
||||
];
|
||||
|
||||
/**
|
||||
* [internal] Track if any filter was applied for at least one column.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $isFilterApplied = false;
|
||||
|
||||
/**
|
||||
* Custom ordering callback.
|
||||
*
|
||||
* @var callable
|
||||
*/
|
||||
protected $orderCallback;
|
||||
|
||||
/**
|
||||
* Skip paginate as needed.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $skipPaging = false;
|
||||
|
||||
/**
|
||||
* Array of data to append on json response.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $appends = [];
|
||||
|
||||
/**
|
||||
* @var \Yajra\DataTables\Utilities\Config
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
protected $serializer;
|
||||
|
||||
/**
|
||||
* Can the DataTable engine be created with these parameters.
|
||||
*
|
||||
* @param mixed $source
|
||||
* @return bool
|
||||
*/
|
||||
public static function canCreate($source)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method, create and return an instance for the DataTable engine.
|
||||
*
|
||||
* @param mixed $source
|
||||
* @return DataTableAbstract
|
||||
*/
|
||||
public static function create($source)
|
||||
{
|
||||
return new static($source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add column in collection.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string|callable $content
|
||||
* @param bool|int $order
|
||||
* @return $this
|
||||
*/
|
||||
public function addColumn($name, $content, $order = false)
|
||||
{
|
||||
$this->extraColumns[] = $name;
|
||||
|
||||
$this->columnDef['append'][] = ['name' => $name, 'content' => $content, 'order' => $order];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add DT row index column on response.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addIndexColumn()
|
||||
{
|
||||
$this->columnDef['index'] = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit column's content.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string|callable $content
|
||||
* @return $this
|
||||
*/
|
||||
public function editColumn($name, $content)
|
||||
{
|
||||
$this->columnDef['edit'][] = ['name' => $name, 'content' => $content];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove column from collection.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function removeColumn()
|
||||
{
|
||||
$names = func_get_args();
|
||||
$this->columnDef['excess'] = array_merge($this->getColumnsDefinition()['excess'], $names);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get only selected columns in response.
|
||||
*
|
||||
* @param array $columns
|
||||
* @return $this
|
||||
*/
|
||||
public function only(array $columns = [])
|
||||
{
|
||||
$this->columnDef['only'] = $columns;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Declare columns to escape values.
|
||||
*
|
||||
* @param string|array $columns
|
||||
* @return $this
|
||||
*/
|
||||
public function escapeColumns($columns = '*')
|
||||
{
|
||||
$this->columnDef['escape'] = $columns;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a makeHidden() to the row object.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @return $this
|
||||
*/
|
||||
public function makeHidden(array $attributes = [])
|
||||
{
|
||||
$this->columnDef['hidden'] = array_merge_recursive(Arr::get($this->columnDef, 'hidden', []), $attributes);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a makeVisible() to the row object.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @return $this
|
||||
*/
|
||||
public function makeVisible(array $attributes = [])
|
||||
{
|
||||
$this->columnDef['visible'] = array_merge_recursive(Arr::get($this->columnDef, 'visible', []), $attributes);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set columns that should not be escaped.
|
||||
* Optionally merge the defaults from config.
|
||||
*
|
||||
* @param array $columns
|
||||
* @param bool $merge
|
||||
* @return $this
|
||||
*/
|
||||
public function rawColumns(array $columns, $merge = false)
|
||||
{
|
||||
if ($merge) {
|
||||
$config = $this->config->get('datatables.columns');
|
||||
|
||||
$this->columnDef['raw'] = array_merge($config['raw'], $columns);
|
||||
} else {
|
||||
$this->columnDef['raw'] = $columns;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets DT_RowClass template.
|
||||
* result: <tr class="output_from_your_template">.
|
||||
*
|
||||
* @param string|callable $content
|
||||
* @return $this
|
||||
*/
|
||||
public function setRowClass($content)
|
||||
{
|
||||
$this->templates['DT_RowClass'] = $content;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets DT_RowId template.
|
||||
* result: <tr id="output_from_your_template">.
|
||||
*
|
||||
* @param string|callable $content
|
||||
* @return $this
|
||||
*/
|
||||
public function setRowId($content)
|
||||
{
|
||||
$this->templates['DT_RowId'] = $content;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set DT_RowData templates.
|
||||
*
|
||||
* @param array $data
|
||||
* @return $this
|
||||
*/
|
||||
public function setRowData(array $data)
|
||||
{
|
||||
$this->templates['DT_RowData'] = $data;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add DT_RowData template.
|
||||
*
|
||||
* @param string $key
|
||||
* @param string|callable $value
|
||||
* @return $this
|
||||
*/
|
||||
public function addRowData($key, $value)
|
||||
{
|
||||
$this->templates['DT_RowData'][$key] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set DT_RowAttr templates.
|
||||
* result: <tr attr1="attr1" attr2="attr2">.
|
||||
*
|
||||
* @param array $data
|
||||
* @return $this
|
||||
*/
|
||||
public function setRowAttr(array $data)
|
||||
{
|
||||
$this->templates['DT_RowAttr'] = $data;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add DT_RowAttr template.
|
||||
*
|
||||
* @param string $key
|
||||
* @param string|callable $value
|
||||
* @return $this
|
||||
*/
|
||||
public function addRowAttr($key, $value)
|
||||
{
|
||||
$this->templates['DT_RowAttr'][$key] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append data on json response.
|
||||
*
|
||||
* @param mixed $key
|
||||
* @param mixed $value
|
||||
* @return $this
|
||||
*/
|
||||
public function with($key, $value = '')
|
||||
{
|
||||
if (is_array($key)) {
|
||||
$this->appends = $key;
|
||||
} elseif (is_callable($value)) {
|
||||
$this->appends[$key] = value($value);
|
||||
} else {
|
||||
$this->appends[$key] = value($value);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add with query callback value on response.
|
||||
*
|
||||
* @param string $key
|
||||
* @param callable $value
|
||||
* @return $this
|
||||
*/
|
||||
public function withQuery($key, callable $value)
|
||||
{
|
||||
$this->appends[$key] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override default ordering method with a closure callback.
|
||||
*
|
||||
* @param callable $closure
|
||||
* @return $this
|
||||
*/
|
||||
public function order(callable $closure)
|
||||
{
|
||||
$this->orderCallback = $closure;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update list of columns that is not allowed for search/sort.
|
||||
*
|
||||
* @param array $blacklist
|
||||
* @return $this
|
||||
*/
|
||||
public function blacklist(array $blacklist)
|
||||
{
|
||||
$this->columnDef['blacklist'] = $blacklist;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update list of columns that is allowed for search/sort.
|
||||
*
|
||||
* @param string|array $whitelist
|
||||
* @return $this
|
||||
*/
|
||||
public function whitelist($whitelist = '*')
|
||||
{
|
||||
$this->columnDef['whitelist'] = $whitelist;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set smart search config at runtime.
|
||||
*
|
||||
* @param bool $state
|
||||
* @return $this
|
||||
*/
|
||||
public function smart($state = true)
|
||||
{
|
||||
$this->config->set('datatables.search.smart', $state);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set starts_with search config at runtime.
|
||||
*
|
||||
* @param bool $state
|
||||
* @return $this
|
||||
*/
|
||||
public function startsWithSearch($state = true)
|
||||
{
|
||||
$this->config->set('datatables.search.starts_with', $state);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set total records manually.
|
||||
*
|
||||
* @param int $total
|
||||
* @return $this
|
||||
*/
|
||||
public function setTotalRecords($total)
|
||||
{
|
||||
$this->totalRecords = $total;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set filtered records manually.
|
||||
*
|
||||
* @param int $total
|
||||
* @return $this
|
||||
*/
|
||||
public function setFilteredRecords($total)
|
||||
{
|
||||
$this->filteredRecords = $total;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Skip pagination as needed.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function skipPaging()
|
||||
{
|
||||
$this->skipPaging = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Push a new column name to blacklist.
|
||||
*
|
||||
* @param string $column
|
||||
* @return $this
|
||||
*/
|
||||
public function pushToBlacklist($column)
|
||||
{
|
||||
if (! $this->isBlacklisted($column)) {
|
||||
$this->columnDef['blacklist'][] = $column;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if column is blacklisted.
|
||||
*
|
||||
* @param string $column
|
||||
* @return bool
|
||||
*/
|
||||
protected function isBlacklisted($column)
|
||||
{
|
||||
$colDef = $this->getColumnsDefinition();
|
||||
|
||||
if (in_array($column, $colDef['blacklist'])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($colDef['whitelist'] === '*' || in_array($column, $colDef['whitelist'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get columns definition.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getColumnsDefinition()
|
||||
{
|
||||
$config = $this->config->get('datatables.columns');
|
||||
$allowed = ['excess', 'escape', 'raw', 'blacklist', 'whitelist'];
|
||||
|
||||
return array_replace_recursive(Arr::only($config, $allowed), $this->columnDef);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform sorting of columns.
|
||||
*/
|
||||
public function ordering()
|
||||
{
|
||||
if ($this->orderCallback) {
|
||||
return call_user_func($this->orderCallback, $this->resolveCallbackParameter());
|
||||
}
|
||||
|
||||
return $this->defaultOrdering();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve callback parameter instance.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
abstract protected function resolveCallbackParameter();
|
||||
|
||||
/**
|
||||
* Perform default query orderBy clause.
|
||||
*/
|
||||
abstract protected function defaultOrdering();
|
||||
|
||||
/**
|
||||
* Set auto filter off and run your own filter.
|
||||
* Overrides global search.
|
||||
*
|
||||
* @param callable $callback
|
||||
* @param bool $globalSearch
|
||||
* @return $this
|
||||
*/
|
||||
public function filter(callable $callback, $globalSearch = false)
|
||||
{
|
||||
$this->autoFilter = $globalSearch;
|
||||
$this->isFilterApplied = true;
|
||||
$this->filterCallback = $callback;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert instance to array.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
return $this->make()->getData(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the object to its JSON representation.
|
||||
*
|
||||
* @param int $options
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function toJson($options = 0)
|
||||
{
|
||||
if ($options) {
|
||||
$this->config->set('datatables.json.options', $options);
|
||||
}
|
||||
|
||||
return $this->make();
|
||||
}
|
||||
|
||||
/**
|
||||
* Count filtered items.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
protected function filteredCount()
|
||||
{
|
||||
return $this->filteredRecords ? $this->filteredRecords : $this->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform necessary filters.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function filterRecords()
|
||||
{
|
||||
if ($this->autoFilter && $this->request->isSearchable()) {
|
||||
$this->filtering();
|
||||
}
|
||||
|
||||
if (is_callable($this->filterCallback)) {
|
||||
call_user_func($this->filterCallback, $this->resolveCallbackParameter());
|
||||
}
|
||||
|
||||
$this->columnSearch();
|
||||
$this->filteredRecords = $this->isFilterApplied ? $this->filteredCount() : $this->totalRecords;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform global search.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function filtering()
|
||||
{
|
||||
$keyword = $this->request->keyword();
|
||||
|
||||
if ($this->config->isMultiTerm()) {
|
||||
$this->smartGlobalSearch($keyword);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->globalSearch($keyword);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform multi-term search by splitting keyword into
|
||||
* individual words and searches for each of them.
|
||||
*
|
||||
* @param string $keyword
|
||||
*/
|
||||
protected function smartGlobalSearch($keyword)
|
||||
{
|
||||
collect(explode(' ', $keyword))
|
||||
->reject(function ($keyword) {
|
||||
return trim($keyword) === '';
|
||||
})
|
||||
->each(function ($keyword) {
|
||||
$this->globalSearch($keyword);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform global search for the given keyword.
|
||||
*
|
||||
* @param string $keyword
|
||||
*/
|
||||
abstract protected function globalSearch($keyword);
|
||||
|
||||
/**
|
||||
* Apply pagination.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function paginate()
|
||||
{
|
||||
if ($this->request->isPaginationable() && ! $this->skipPaging) {
|
||||
$this->paging();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform output.
|
||||
*
|
||||
* @param mixed $results
|
||||
* @param mixed $processed
|
||||
* @return array
|
||||
*/
|
||||
protected function transform($results, $processed)
|
||||
{
|
||||
if (isset($this->transformer) && class_exists('Yajra\\DataTables\\Transformers\\FractalTransformer')) {
|
||||
return app('datatables.transformer')->transform(
|
||||
$results,
|
||||
$this->transformer,
|
||||
$this->serializer ?? null
|
||||
);
|
||||
}
|
||||
|
||||
return Helper::transform($processed);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get processed data.
|
||||
*
|
||||
* @param mixed $results
|
||||
* @param bool $object
|
||||
* @return array
|
||||
*/
|
||||
protected function processResults($results, $object = false)
|
||||
{
|
||||
$processor = new DataProcessor(
|
||||
$results,
|
||||
$this->getColumnsDefinition(),
|
||||
$this->templates,
|
||||
$this->request->input('start')
|
||||
);
|
||||
|
||||
return $processor->process($object);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render json response.
|
||||
*
|
||||
* @param array $data
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
protected function render(array $data)
|
||||
{
|
||||
$output = $this->attachAppends([
|
||||
'draw' => (int) $this->request->input('draw'),
|
||||
'recordsTotal' => $this->totalRecords,
|
||||
'recordsFiltered' => $this->filteredRecords,
|
||||
'data' => $data,
|
||||
]);
|
||||
|
||||
if ($this->config->isDebugging()) {
|
||||
$output = $this->showDebugger($output);
|
||||
}
|
||||
|
||||
return new JsonResponse(
|
||||
$output,
|
||||
200,
|
||||
$this->config->get('datatables.json.header', []),
|
||||
$this->config->get('datatables.json.options', 0)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attach custom with meta on response.
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
protected function attachAppends(array $data)
|
||||
{
|
||||
return array_merge($data, $this->appends);
|
||||
}
|
||||
|
||||
/**
|
||||
* Append debug parameters on output.
|
||||
*
|
||||
* @param array $output
|
||||
* @return array
|
||||
*/
|
||||
protected function showDebugger(array $output)
|
||||
{
|
||||
$output['input'] = $this->request->all();
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an error json response.
|
||||
*
|
||||
* @param \Exception $exception
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @throws \Yajra\DataTables\Exceptions\Exception
|
||||
*/
|
||||
protected function errorResponse(\Exception $exception)
|
||||
{
|
||||
$error = $this->config->get('datatables.error');
|
||||
$debug = $this->config->get('app.debug');
|
||||
|
||||
if ($error === 'throw' || (! $error && ! $debug)) {
|
||||
throw new Exception($exception->getMessage(), $code = 0, $exception);
|
||||
}
|
||||
|
||||
$this->getLogger()->error($exception);
|
||||
|
||||
return new JsonResponse([
|
||||
'draw' => (int) $this->request->input('draw'),
|
||||
'recordsTotal' => $this->totalRecords,
|
||||
'recordsFiltered' => 0,
|
||||
'data' => [],
|
||||
'error' => $error ? __($error) : "Exception Message:\n\n".$exception->getMessage(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get monolog/logger instance.
|
||||
*
|
||||
* @return \Psr\Log\LoggerInterface
|
||||
*/
|
||||
public function getLogger()
|
||||
{
|
||||
$this->logger = $this->logger ?: app(LoggerInterface::class);
|
||||
|
||||
return $this->logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set monolog/logger instance.
|
||||
*
|
||||
* @param \Psr\Log\LoggerInterface $logger
|
||||
* @return $this
|
||||
*/
|
||||
public function setLogger(LoggerInterface $logger)
|
||||
{
|
||||
$this->logger = $logger;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup search keyword.
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
protected function setupKeyword($value)
|
||||
{
|
||||
if ($this->config->isSmartSearch()) {
|
||||
$keyword = '%'.$value.'%';
|
||||
if ($this->config->isWildcard()) {
|
||||
$keyword = Helper::wildcardLikeString($value);
|
||||
}
|
||||
// remove escaping slash added on js script request
|
||||
$keyword = str_replace('\\', '%', $keyword);
|
||||
|
||||
return $keyword;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get column name to be use for filtering and sorting.
|
||||
*
|
||||
* @param int $index
|
||||
* @param bool $wantsAlias
|
||||
* @return string
|
||||
*/
|
||||
protected function getColumnName($index, $wantsAlias = false)
|
||||
{
|
||||
$column = $this->request->columnName($index);
|
||||
|
||||
// DataTables is using make(false)
|
||||
if (is_numeric($column)) {
|
||||
$column = $this->getColumnNameByIndex($index);
|
||||
}
|
||||
|
||||
if (Str::contains(Str::upper($column), ' AS ')) {
|
||||
$column = Helper::extractColumnName($column, $wantsAlias);
|
||||
}
|
||||
|
||||
return $column;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get column name by order column index.
|
||||
*
|
||||
* @param int $index
|
||||
* @return string
|
||||
*/
|
||||
protected function getColumnNameByIndex($index)
|
||||
{
|
||||
$name = (isset($this->columns[$index]) && $this->columns[$index] != '*')
|
||||
? $this->columns[$index] : $this->getPrimaryKeyName();
|
||||
|
||||
return in_array($name, $this->extraColumns, true) ? $this->getPrimaryKeyName() : $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* If column name could not be resolved then use primary key.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getPrimaryKeyName()
|
||||
{
|
||||
return 'id';
|
||||
}
|
||||
}
|
154
vendor/yajra/laravel-datatables-oracle/src/DataTables.php
vendored
Normal file
154
vendor/yajra/laravel-datatables-oracle/src/DataTables.php
vendored
Normal file
@@ -0,0 +1,154 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\DataTables;
|
||||
|
||||
use Illuminate\Support\Traits\Macroable;
|
||||
|
||||
class DataTables
|
||||
{
|
||||
use Macroable;
|
||||
|
||||
/**
|
||||
* DataTables request object.
|
||||
*
|
||||
* @var \Yajra\DataTables\Utilities\Request
|
||||
*/
|
||||
protected $request;
|
||||
|
||||
/**
|
||||
* HTML builder instance.
|
||||
*
|
||||
* @var \Yajra\DataTables\Html\Builder
|
||||
*/
|
||||
protected $html;
|
||||
|
||||
/**
|
||||
* Make a DataTable instance from source.
|
||||
* Alias of make for backward compatibility.
|
||||
*
|
||||
* @param mixed $source
|
||||
* @return mixed
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function of($source)
|
||||
{
|
||||
return self::make($source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a DataTable instance from source.
|
||||
*
|
||||
* @param mixed $source
|
||||
* @return mixed
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function make($source)
|
||||
{
|
||||
$engines = config('datatables.engines');
|
||||
$builders = config('datatables.builders');
|
||||
|
||||
$args = func_get_args();
|
||||
foreach ($builders as $class => $engine) {
|
||||
if ($source instanceof $class) {
|
||||
return call_user_func_array([$engines[$engine], 'create'], $args);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($engines as $engine => $class) {
|
||||
if (call_user_func_array([$engines[$engine], 'canCreate'], $args)) {
|
||||
return call_user_func_array([$engines[$engine], 'create'], $args);
|
||||
}
|
||||
}
|
||||
|
||||
throw new \Exception('No available engine for ' . get_class($source));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get request object.
|
||||
*
|
||||
* @return \Yajra\DataTables\Utilities\Request
|
||||
*/
|
||||
public function getRequest()
|
||||
{
|
||||
return app('datatables.request');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get config instance.
|
||||
*
|
||||
* @return \Yajra\DataTables\Utilities\Config
|
||||
*/
|
||||
public function getConfig()
|
||||
{
|
||||
return app('datatables.config');
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Please use query() instead, this method will be removed in a next version.
|
||||
* @param $builder
|
||||
* @return QueryDataTable
|
||||
*/
|
||||
public function queryBuilder($builder)
|
||||
{
|
||||
return $this->query($builder);
|
||||
}
|
||||
|
||||
/**
|
||||
* DataTables using Query.
|
||||
*
|
||||
* @param \Illuminate\Database\Query\Builder|mixed $builder
|
||||
* @return DataTableAbstract|QueryDataTable
|
||||
*/
|
||||
public function query($builder)
|
||||
{
|
||||
return QueryDataTable::create($builder);
|
||||
}
|
||||
|
||||
/**
|
||||
* DataTables using Eloquent Builder.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder|mixed $builder
|
||||
* @return DataTableAbstract|EloquentDataTable
|
||||
*/
|
||||
public function eloquent($builder)
|
||||
{
|
||||
return EloquentDataTable::create($builder);
|
||||
}
|
||||
|
||||
/**
|
||||
* DataTables using Collection.
|
||||
*
|
||||
* @param \Illuminate\Support\Collection|array $collection
|
||||
* @return DataTableAbstract|CollectionDataTable
|
||||
*/
|
||||
public function collection($collection)
|
||||
{
|
||||
return CollectionDataTable::create($collection);
|
||||
}
|
||||
|
||||
/**
|
||||
* DataTables using Collection.
|
||||
*
|
||||
* @param \Illuminate\Http\Resources\Json\AnonymousResourceCollection|array $collection
|
||||
* @return DataTableAbstract|ApiResourceDataTable
|
||||
*/
|
||||
public function resource($resource)
|
||||
{
|
||||
return ApiResourceDataTable::create($resource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get html builder instance.
|
||||
*
|
||||
* @return \Yajra\DataTables\Html\Builder
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getHtmlBuilder()
|
||||
{
|
||||
if (! class_exists('\Yajra\DataTables\Html\Builder')) {
|
||||
throw new \Exception('Please install yajra/laravel-datatables-html to be able to use this function.');
|
||||
}
|
||||
|
||||
return $this->html ?: $this->html = app('datatables.html');
|
||||
}
|
||||
}
|
83
vendor/yajra/laravel-datatables-oracle/src/DataTablesServiceProvider.php
vendored
Normal file
83
vendor/yajra/laravel-datatables-oracle/src/DataTablesServiceProvider.php
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\DataTables;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Illuminate\Support\Str;
|
||||
use Yajra\DataTables\Utilities\Config;
|
||||
use Yajra\DataTables\Utilities\Request;
|
||||
|
||||
class DataTablesServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Register the service provider.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
if ($this->isLumen()) {
|
||||
require_once 'lumen.php';
|
||||
}
|
||||
|
||||
$this->setupAssets();
|
||||
|
||||
$this->app->alias('datatables', DataTables::class);
|
||||
$this->app->singleton('datatables', function () {
|
||||
return new DataTables;
|
||||
});
|
||||
|
||||
$this->app->singleton('datatables.request', function () {
|
||||
return new Request;
|
||||
});
|
||||
|
||||
$this->app->singleton('datatables.config', Config::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Boot the instance, add macros for datatable engines.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
$engines = (array) config('datatables.engines');
|
||||
foreach ($engines as $engine => $class) {
|
||||
$engine = Str::camel($engine);
|
||||
|
||||
if (! method_exists(DataTables::class, $engine) && ! DataTables::hasMacro($engine)) {
|
||||
DataTables::macro($engine, function () use ($class) {
|
||||
if (! call_user_func_array([$class, 'canCreate'], func_get_args())) {
|
||||
throw new \InvalidArgumentException();
|
||||
}
|
||||
|
||||
return call_user_func_array([$class, 'create'], func_get_args());
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup package assets.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function setupAssets()
|
||||
{
|
||||
$this->mergeConfigFrom($config = __DIR__ . '/config/datatables.php', 'datatables');
|
||||
|
||||
if ($this->app->runningInConsole()) {
|
||||
$this->publishes([$config => config_path('datatables.php')], 'datatables');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if app uses Lumen.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isLumen()
|
||||
{
|
||||
return Str::contains($this->app->version(), 'Lumen');
|
||||
}
|
||||
}
|
@@ -1,136 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\Datatables;
|
||||
|
||||
use Illuminate\Database\Query\Builder as QueryBuilder;
|
||||
use Illuminate\Support\Collection;
|
||||
use Yajra\Datatables\Engines\CollectionEngine;
|
||||
use Yajra\Datatables\Engines\EloquentEngine;
|
||||
use Yajra\Datatables\Engines\QueryBuilderEngine;
|
||||
|
||||
/**
|
||||
* Class Datatables.
|
||||
*
|
||||
* @package Yajra\Datatables
|
||||
* @method EloquentEngine eloquent($builder)
|
||||
* @method CollectionEngine collection(Collection $builder)
|
||||
* @method QueryBuilderEngine queryBuilder(QueryBuilder $builder)
|
||||
* @author Arjay Angeles <aqangeles@gmail.com>
|
||||
*/
|
||||
class Datatables
|
||||
{
|
||||
/**
|
||||
* Datatables request object.
|
||||
*
|
||||
* @var \Yajra\Datatables\Request
|
||||
*/
|
||||
public $request;
|
||||
|
||||
/**
|
||||
* Datatables builder.
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
public $builder;
|
||||
|
||||
/**
|
||||
* Datatables constructor.
|
||||
*
|
||||
* @param \Yajra\Datatables\Request $request
|
||||
*/
|
||||
public function __construct(Request $request)
|
||||
{
|
||||
$this->request = $request->request->count() ? $request : Request::capture();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets query and returns instance of class.
|
||||
*
|
||||
* @param mixed $builder
|
||||
* @return mixed
|
||||
*/
|
||||
public static function of($builder)
|
||||
{
|
||||
$datatables = app('Yajra\Datatables\Datatables');
|
||||
$datatables->builder = $builder;
|
||||
|
||||
if ($builder instanceof QueryBuilder) {
|
||||
$ins = $datatables->usingQueryBuilder($builder);
|
||||
} else {
|
||||
$ins = $builder instanceof Collection ? $datatables->usingCollection($builder) : $datatables->usingEloquent($builder);
|
||||
}
|
||||
|
||||
return $ins;
|
||||
}
|
||||
|
||||
/**
|
||||
* Datatables using Query Builder.
|
||||
*
|
||||
* @param \Illuminate\Database\Query\Builder $builder
|
||||
* @return \Yajra\Datatables\Engines\QueryBuilderEngine
|
||||
*/
|
||||
public function usingQueryBuilder(QueryBuilder $builder)
|
||||
{
|
||||
return new QueryBuilderEngine($builder, $this->request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Datatables using Collection.
|
||||
*
|
||||
* @param \Illuminate\Support\Collection $builder
|
||||
* @return \Yajra\Datatables\Engines\CollectionEngine
|
||||
*/
|
||||
public function usingCollection(Collection $builder)
|
||||
{
|
||||
return new CollectionEngine($builder, $this->request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Datatables using Eloquent.
|
||||
*
|
||||
* @param mixed $builder
|
||||
* @return \Yajra\Datatables\Engines\EloquentEngine
|
||||
*/
|
||||
public function usingEloquent($builder)
|
||||
{
|
||||
return new EloquentEngine($builder, $this->request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows api call without the "using" word.
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $arguments
|
||||
* @return $this|mixed
|
||||
*/
|
||||
public function __call($name, $arguments)
|
||||
{
|
||||
$name = 'using' . ucfirst($name);
|
||||
|
||||
if (method_exists($this, $name)) {
|
||||
return call_user_func_array([$this, $name], $arguments);
|
||||
}
|
||||
|
||||
return trigger_error('Call to undefined method ' . __CLASS__ . '::' . $name . '()', E_USER_ERROR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get html builder class.
|
||||
*
|
||||
* @return \Yajra\Datatables\Html\Builder
|
||||
*/
|
||||
public function getHtmlBuilder()
|
||||
{
|
||||
return app('Yajra\Datatables\Html\Builder');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get request object.
|
||||
*
|
||||
* @return \Yajra\Datatables\Request|static
|
||||
*/
|
||||
public function getRequest()
|
||||
{
|
||||
return $this->request;
|
||||
}
|
||||
}
|
@@ -1,144 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\Datatables;
|
||||
|
||||
use Collective\Html\HtmlServiceProvider;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use League\Fractal\Manager;
|
||||
use League\Fractal\Serializer\DataArraySerializer;
|
||||
use Maatwebsite\Excel\ExcelServiceProvider;
|
||||
use Yajra\Datatables\Generators\DataTablesMakeCommand;
|
||||
use Yajra\Datatables\Generators\DataTablesScopeCommand;
|
||||
|
||||
/**
|
||||
* Class DatatablesServiceProvider.
|
||||
*
|
||||
* @package Yajra\Datatables
|
||||
* @author Arjay Angeles <aqangeles@gmail.com>
|
||||
*/
|
||||
class DatatablesServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Indicates if loading of the provider is deferred.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $defer = false;
|
||||
|
||||
/**
|
||||
* Bootstrap the application events.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
$this->loadViewsFrom(__DIR__ . '/resources/views', 'datatables');
|
||||
|
||||
$this->publishAssets();
|
||||
|
||||
$this->registerCommands();
|
||||
}
|
||||
|
||||
/**
|
||||
* Publish datatables assets.
|
||||
*/
|
||||
protected function publishAssets()
|
||||
{
|
||||
$this->publishes([
|
||||
__DIR__ . '/config/config.php' => config_path('datatables.php'),
|
||||
], 'datatables');
|
||||
|
||||
$this->publishes([
|
||||
__DIR__ . '/resources/assets/buttons.server-side.js' => public_path('vendor/datatables/buttons.server-side.js'),
|
||||
], 'datatables');
|
||||
|
||||
$this->publishes([
|
||||
__DIR__ . '/resources/views' => base_path('/resources/views/vendor/datatables'),
|
||||
], 'datatables');
|
||||
}
|
||||
|
||||
/**
|
||||
* Register datatables commands.
|
||||
*/
|
||||
protected function registerCommands()
|
||||
{
|
||||
$this->commands(DataTablesMakeCommand::class);
|
||||
$this->commands(DataTablesScopeCommand::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the service provider.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
if ($this->isLumen()) {
|
||||
require_once 'fallback.php';
|
||||
}
|
||||
|
||||
$this->registerRequiredProviders();
|
||||
|
||||
$this->app->singleton('datatables', function () {
|
||||
return new Datatables($this->app->make(Request::class));
|
||||
});
|
||||
|
||||
$this->app->singleton('datatables.fractal', function () {
|
||||
$fractal = new Manager;
|
||||
$config = $this->app['config'];
|
||||
$request = $this->app['request'];
|
||||
|
||||
$includesKey = $config->get('datatables.fractal.includes', 'include');
|
||||
if ($request->get($includesKey)) {
|
||||
$fractal->parseIncludes($request->get($includesKey));
|
||||
}
|
||||
|
||||
$serializer = $config->get('datatables.fractal.serializer', DataArraySerializer::class);
|
||||
$fractal->setSerializer(new $serializer);
|
||||
|
||||
return $fractal;
|
||||
});
|
||||
|
||||
$this->registerAliases();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if app uses Lumen.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isLumen()
|
||||
{
|
||||
return str_contains($this->app->version(), 'Lumen');
|
||||
}
|
||||
|
||||
/**
|
||||
* Register 3rd party providers.
|
||||
*/
|
||||
protected function registerRequiredProviders()
|
||||
{
|
||||
$this->app->register(HtmlServiceProvider::class);
|
||||
$this->app->register(ExcelServiceProvider::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create aliases for the dependency.
|
||||
*/
|
||||
protected function registerAliases()
|
||||
{
|
||||
if (class_exists('Illuminate\Foundation\AliasLoader')) {
|
||||
$loader = \Illuminate\Foundation\AliasLoader::getInstance();
|
||||
$loader->alias('Datatables', \Yajra\Datatables\Facades\Datatables::class);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the services provided by the provider.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function provides()
|
||||
{
|
||||
return ['datatables'];
|
||||
}
|
||||
}
|
218
vendor/yajra/laravel-datatables-oracle/src/EloquentDataTable.php
vendored
Normal file
218
vendor/yajra/laravel-datatables-oracle/src/EloquentDataTable.php
vendored
Normal file
@@ -0,0 +1,218 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\DataTables;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasOneOrMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasOneThrough;
|
||||
use Illuminate\Database\Eloquent\Relations\Relation;
|
||||
use Yajra\DataTables\Exceptions\Exception;
|
||||
|
||||
class EloquentDataTable extends QueryDataTable
|
||||
{
|
||||
/**
|
||||
* @var \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
protected $query;
|
||||
|
||||
/**
|
||||
* Can the DataTable engine be created with these parameters.
|
||||
*
|
||||
* @param mixed $source
|
||||
* @return bool
|
||||
*/
|
||||
public static function canCreate($source)
|
||||
{
|
||||
return $source instanceof Builder || $source instanceof Relation;
|
||||
}
|
||||
|
||||
/**
|
||||
* EloquentEngine constructor.
|
||||
*
|
||||
* @param mixed $model
|
||||
*/
|
||||
public function __construct($model)
|
||||
{
|
||||
$builder = $model instanceof Builder ? $model : $model->getQuery();
|
||||
parent::__construct($builder->getQuery());
|
||||
|
||||
$this->query = $builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add columns in collection.
|
||||
*
|
||||
* @param array $names
|
||||
* @param bool|int $order
|
||||
* @return $this
|
||||
*/
|
||||
public function addColumns(array $names, $order = false)
|
||||
{
|
||||
foreach ($names as $name => $attribute) {
|
||||
if (is_int($name)) {
|
||||
$name = $attribute;
|
||||
}
|
||||
|
||||
$this->addColumn($name, function ($model) use ($attribute) {
|
||||
return $model->getAttribute($attribute);
|
||||
}, is_int($order) ? $order++ : $order);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* If column name could not be resolved then use primary key.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getPrimaryKeyName()
|
||||
{
|
||||
return $this->query->getModel()->getKeyName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile query builder where clause depending on configurations.
|
||||
*
|
||||
* @param mixed $query
|
||||
* @param string $columnName
|
||||
* @param string $keyword
|
||||
* @param string $boolean
|
||||
*/
|
||||
protected function compileQuerySearch($query, $columnName, $keyword, $boolean = 'or')
|
||||
{
|
||||
$parts = explode('.', $columnName);
|
||||
$column = array_pop($parts);
|
||||
$relation = implode('.', $parts);
|
||||
|
||||
if ($this->isNotEagerLoaded($relation)) {
|
||||
return parent::compileQuerySearch($query, $columnName, $keyword, $boolean);
|
||||
}
|
||||
|
||||
$query->{$boolean . 'WhereHas'}($relation, function (Builder $query) use ($column, $keyword) {
|
||||
parent::compileQuerySearch($query, $column, $keyword, '');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the proper column name be used.
|
||||
*
|
||||
* @param string $column
|
||||
* @return string
|
||||
*/
|
||||
protected function resolveRelationColumn($column)
|
||||
{
|
||||
$parts = explode('.', $column);
|
||||
$columnName = array_pop($parts);
|
||||
$relation = implode('.', $parts);
|
||||
|
||||
if ($this->isNotEagerLoaded($relation)) {
|
||||
return $column;
|
||||
}
|
||||
|
||||
return $this->joinEagerLoadedColumn($relation, $columnName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a relation was not used on eager loading.
|
||||
*
|
||||
* @param string $relation
|
||||
* @return bool
|
||||
*/
|
||||
protected function isNotEagerLoaded($relation)
|
||||
{
|
||||
return ! $relation
|
||||
|| ! array_key_exists($relation, $this->query->getEagerLoads())
|
||||
|| $relation === $this->query->getModel()->getTable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Join eager loaded relation and get the related column name.
|
||||
*
|
||||
* @param string $relation
|
||||
* @param string $relationColumn
|
||||
* @return string
|
||||
* @throws \Yajra\DataTables\Exceptions\Exception
|
||||
*/
|
||||
protected function joinEagerLoadedColumn($relation, $relationColumn)
|
||||
{
|
||||
$table = '';
|
||||
$lastQuery = $this->query;
|
||||
foreach (explode('.', $relation) as $eachRelation) {
|
||||
$model = $lastQuery->getRelation($eachRelation);
|
||||
switch (true) {
|
||||
case $model instanceof BelongsToMany:
|
||||
$pivot = $model->getTable();
|
||||
$pivotPK = $model->getExistenceCompareKey();
|
||||
$pivotFK = $model->getQualifiedParentKeyName();
|
||||
$this->performJoin($pivot, $pivotPK, $pivotFK);
|
||||
|
||||
$related = $model->getRelated();
|
||||
$table = $related->getTable();
|
||||
$tablePK = $related->getForeignKey();
|
||||
$foreign = $pivot . '.' . $tablePK;
|
||||
$other = $related->getQualifiedKeyName();
|
||||
|
||||
$lastQuery->addSelect($table . '.' . $relationColumn);
|
||||
$this->performJoin($table, $foreign, $other);
|
||||
|
||||
break;
|
||||
|
||||
case $model instanceof HasOneThrough:
|
||||
$pivot = explode('.', $model->getQualifiedParentKeyName())[0]; // extract pivot table from key
|
||||
$pivotPK = $pivot . '.' . $model->getLocalKeyName();
|
||||
$pivotFK = $model->getQualifiedLocalKeyName();
|
||||
$this->performJoin($pivot, $pivotPK, $pivotFK);
|
||||
|
||||
$related = $model->getRelated();
|
||||
$table = $related->getTable();
|
||||
$tablePK = $related->getForeignKey();
|
||||
$foreign = $pivot . '.' . $tablePK;
|
||||
$other = $related->getQualifiedKeyName();
|
||||
|
||||
break;
|
||||
|
||||
case $model instanceof HasOneOrMany:
|
||||
$table = $model->getRelated()->getTable();
|
||||
$foreign = $model->getQualifiedForeignKeyName();
|
||||
$other = $model->getQualifiedParentKeyName();
|
||||
break;
|
||||
|
||||
case $model instanceof BelongsTo:
|
||||
$table = $model->getRelated()->getTable();
|
||||
$foreign = $model->getQualifiedForeignKeyName();
|
||||
$other = $model->getQualifiedOwnerKeyName();
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Exception('Relation ' . get_class($model) . ' is not yet supported.');
|
||||
}
|
||||
$this->performJoin($table, $foreign, $other);
|
||||
$lastQuery = $model->getQuery();
|
||||
}
|
||||
|
||||
return $table . '.' . $relationColumn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform join query.
|
||||
*
|
||||
* @param string $table
|
||||
* @param string $foreign
|
||||
* @param string $other
|
||||
* @param string $type
|
||||
*/
|
||||
protected function performJoin($table, $foreign, $other, $type = 'left')
|
||||
{
|
||||
$joins = [];
|
||||
foreach ((array) $this->getBaseQueryBuilder()->joins as $key => $join) {
|
||||
$joins[] = $join->table;
|
||||
}
|
||||
|
||||
if (! in_array($table, $joins)) {
|
||||
$this->getBaseQueryBuilder()->join($table, $foreign, '=', $other, $type);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,967 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\Datatables\Engines;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Facades\Config;
|
||||
use Illuminate\Support\Str;
|
||||
use League\Fractal\Resource\Collection;
|
||||
use Yajra\Datatables\Contracts\DataTableEngineContract;
|
||||
use Yajra\Datatables\Helper;
|
||||
use Yajra\Datatables\Processors\DataProcessor;
|
||||
|
||||
/**
|
||||
* Class BaseEngine.
|
||||
*
|
||||
* @package Yajra\Datatables\Engines
|
||||
* @author Arjay Angeles <aqangeles@gmail.com>
|
||||
*/
|
||||
abstract class BaseEngine implements DataTableEngineContract
|
||||
{
|
||||
/**
|
||||
* Datatables Request object.
|
||||
*
|
||||
* @var \Yajra\Datatables\Request
|
||||
*/
|
||||
public $request;
|
||||
|
||||
/**
|
||||
* Database connection used.
|
||||
*
|
||||
* @var \Illuminate\Database\Connection
|
||||
*/
|
||||
protected $connection;
|
||||
|
||||
/**
|
||||
* Builder object.
|
||||
*
|
||||
* @var \Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
protected $query;
|
||||
|
||||
/**
|
||||
* Query builder object.
|
||||
*
|
||||
* @var \Illuminate\Database\Query\Builder
|
||||
*/
|
||||
protected $builder;
|
||||
|
||||
/**
|
||||
* Array of result columns/fields.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $columns = [];
|
||||
|
||||
/**
|
||||
* DT columns definitions container (add/edit/remove/filter/order/escape).
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $columnDef = [
|
||||
'index' => false,
|
||||
'append' => [],
|
||||
'edit' => [],
|
||||
'excess' => ['rn', 'row_num'],
|
||||
'filter' => [],
|
||||
'order' => [],
|
||||
'escape' => [],
|
||||
'blacklist' => ['password', 'remember_token'],
|
||||
'whitelist' => '*',
|
||||
];
|
||||
|
||||
/**
|
||||
* Query type.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $query_type;
|
||||
|
||||
/**
|
||||
* Extra/Added columns.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $extraColumns = [];
|
||||
|
||||
/**
|
||||
* Total records.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $totalRecords = 0;
|
||||
|
||||
/**
|
||||
* Total filtered records.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $filteredRecords = 0;
|
||||
|
||||
/**
|
||||
* Auto-filter flag.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $autoFilter = true;
|
||||
|
||||
/**
|
||||
* Callback to override global search.
|
||||
*
|
||||
* @var \Closure
|
||||
*/
|
||||
protected $filterCallback;
|
||||
|
||||
/**
|
||||
* Parameters to passed on filterCallback.
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
protected $filterCallbackParameters;
|
||||
|
||||
/**
|
||||
* DT row templates container.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $templates = [
|
||||
'DT_RowId' => '',
|
||||
'DT_RowClass' => '',
|
||||
'DT_RowData' => [],
|
||||
'DT_RowAttr' => [],
|
||||
];
|
||||
|
||||
/**
|
||||
* Output transformer.
|
||||
*
|
||||
* @var \League\Fractal\TransformerAbstract
|
||||
*/
|
||||
protected $transformer = null;
|
||||
|
||||
/**
|
||||
* Database prefix
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $prefix;
|
||||
|
||||
/**
|
||||
* Database driver used.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $database;
|
||||
|
||||
/**
|
||||
* [internal] Track if any filter was applied for at least one column
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
protected $isFilterApplied = false;
|
||||
|
||||
/**
|
||||
* Fractal serializer class.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
protected $serializer = null;
|
||||
|
||||
/**
|
||||
* Custom ordering callback.
|
||||
*
|
||||
* @var \Closure
|
||||
*/
|
||||
protected $orderCallback;
|
||||
|
||||
/**
|
||||
* Array of data to append on json response.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $appends = [];
|
||||
|
||||
/**
|
||||
* Setup search keyword.
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
public function setupKeyword($value)
|
||||
{
|
||||
if ($this->isSmartSearch()) {
|
||||
$keyword = '%' . $value . '%';
|
||||
if ($this->isWildcard()) {
|
||||
$keyword = $this->wildcardLikeString($value);
|
||||
}
|
||||
// remove escaping slash added on js script request
|
||||
$keyword = str_replace('\\', '%', $keyword);
|
||||
|
||||
return $keyword;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if DataTables uses smart search.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isSmartSearch()
|
||||
{
|
||||
return Config::get('datatables.search.smart', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get config use wild card status.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isWildcard()
|
||||
{
|
||||
return Config::get('datatables.search.use_wildcards', false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds % wildcards to the given string.
|
||||
*
|
||||
* @param string $str
|
||||
* @param bool $lowercase
|
||||
* @return string
|
||||
*/
|
||||
public function wildcardLikeString($str, $lowercase = true)
|
||||
{
|
||||
$wild = '%';
|
||||
$length = Str::length($str);
|
||||
if ($length) {
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
$wild .= $str[$i] . '%';
|
||||
}
|
||||
}
|
||||
if ($lowercase) {
|
||||
$wild = Str::lower($wild);
|
||||
}
|
||||
|
||||
return $wild;
|
||||
}
|
||||
|
||||
/**
|
||||
* Will prefix column if needed.
|
||||
*
|
||||
* @param string $column
|
||||
* @return string
|
||||
*/
|
||||
public function prefixColumn($column)
|
||||
{
|
||||
$table_names = $this->tableNames();
|
||||
if (count(
|
||||
array_filter($table_names, function ($value) use (&$column) {
|
||||
return strpos($column, $value . '.') === 0;
|
||||
})
|
||||
)) {
|
||||
// the column starts with one of the table names
|
||||
$column = $this->prefix . $column;
|
||||
}
|
||||
|
||||
return $column;
|
||||
}
|
||||
|
||||
/**
|
||||
* Will look through the query and all it's joins to determine the table names.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function tableNames()
|
||||
{
|
||||
$names = [];
|
||||
$query = $this->getQueryBuilder();
|
||||
$names[] = $query->from;
|
||||
$joins = $query->joins ?: [];
|
||||
$databasePrefix = $this->prefix;
|
||||
foreach ($joins as $join) {
|
||||
$table = preg_split('/ as /i', $join->table);
|
||||
$names[] = $table[0];
|
||||
if (isset($table[1]) && ! empty($databasePrefix) && strpos($table[1], $databasePrefix) == 0) {
|
||||
$names[] = preg_replace('/^' . $databasePrefix . '/', '', $table[1]);
|
||||
}
|
||||
}
|
||||
|
||||
return $names;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Query Builder object.
|
||||
*
|
||||
* @param mixed $instance
|
||||
* @return mixed
|
||||
*/
|
||||
public function getQueryBuilder($instance = null)
|
||||
{
|
||||
if (! $instance) {
|
||||
$instance = $this->query;
|
||||
}
|
||||
|
||||
if ($this->isQueryBuilder()) {
|
||||
return $instance;
|
||||
}
|
||||
|
||||
return $instance->getQuery();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check query type is a builder.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isQueryBuilder()
|
||||
{
|
||||
return $this->query_type == 'builder';
|
||||
}
|
||||
|
||||
/**
|
||||
* Add column in collection.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string|callable $content
|
||||
* @param bool|int $order
|
||||
* @return $this
|
||||
*/
|
||||
public function addColumn($name, $content, $order = false)
|
||||
{
|
||||
$this->extraColumns[] = $name;
|
||||
|
||||
$this->columnDef['append'][] = ['name' => $name, 'content' => $content, 'order' => $order];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add DT row index column on response.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addIndexColumn()
|
||||
{
|
||||
$this->columnDef['index'] = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit column's content.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string|callable $content
|
||||
* @return $this
|
||||
*/
|
||||
public function editColumn($name, $content)
|
||||
{
|
||||
$this->columnDef['edit'][] = ['name' => $name, 'content' => $content];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove column from collection.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function removeColumn()
|
||||
{
|
||||
$names = func_get_args();
|
||||
$this->columnDef['excess'] = array_merge($this->columnDef['excess'], $names);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Declare columns to escape values.
|
||||
*
|
||||
* @param string|array $columns
|
||||
* @return $this
|
||||
*/
|
||||
public function escapeColumns($columns = '*')
|
||||
{
|
||||
$this->columnDef['escape'] = $columns;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows previous API calls where the methods were snake_case.
|
||||
* Will convert a camelCase API call to a snake_case call.
|
||||
* Allow query builder method to be used by the engine.
|
||||
*
|
||||
* @param string $name
|
||||
* @param array $arguments
|
||||
* @return mixed
|
||||
*/
|
||||
public function __call($name, $arguments)
|
||||
{
|
||||
$name = Str::camel(Str::lower($name));
|
||||
if (method_exists($this, $name)) {
|
||||
return call_user_func_array([$this, $name], $arguments);
|
||||
} elseif (method_exists($this->getQueryBuilder(), $name)) {
|
||||
call_user_func_array([$this->getQueryBuilder(), $name], $arguments);
|
||||
} else {
|
||||
trigger_error('Call to undefined method ' . __CLASS__ . '::' . $name . '()', E_USER_ERROR);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets DT_RowClass template.
|
||||
* result: <tr class="output_from_your_template">.
|
||||
*
|
||||
* @param string|callable $content
|
||||
* @return $this
|
||||
*/
|
||||
public function setRowClass($content)
|
||||
{
|
||||
$this->templates['DT_RowClass'] = $content;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets DT_RowId template.
|
||||
* result: <tr id="output_from_your_template">.
|
||||
*
|
||||
* @param string|callable $content
|
||||
* @return $this
|
||||
*/
|
||||
public function setRowId($content)
|
||||
{
|
||||
$this->templates['DT_RowId'] = $content;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set DT_RowData templates.
|
||||
*
|
||||
* @param array $data
|
||||
* @return $this
|
||||
*/
|
||||
public function setRowData(array $data)
|
||||
{
|
||||
$this->templates['DT_RowData'] = $data;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add DT_RowData template.
|
||||
*
|
||||
* @param string $key
|
||||
* @param string|callable $value
|
||||
* @return $this
|
||||
*/
|
||||
public function addRowData($key, $value)
|
||||
{
|
||||
$this->templates['DT_RowData'][$key] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set DT_RowAttr templates.
|
||||
* result: <tr attr1="attr1" attr2="attr2">.
|
||||
*
|
||||
* @param array $data
|
||||
* @return $this
|
||||
*/
|
||||
public function setRowAttr(array $data)
|
||||
{
|
||||
$this->templates['DT_RowAttr'] = $data;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add DT_RowAttr template.
|
||||
*
|
||||
* @param string $key
|
||||
* @param string|callable $value
|
||||
* @return $this
|
||||
*/
|
||||
public function addRowAttr($key, $value)
|
||||
{
|
||||
$this->templates['DT_RowAttr'][$key] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override default column filter search.
|
||||
*
|
||||
* @param string $column
|
||||
* @param string|Closure $method
|
||||
* @return $this
|
||||
* @internal param $mixed ...,... All the individual parameters required for specified $method
|
||||
* @internal string $1 Special variable that returns the requested search keyword.
|
||||
*/
|
||||
public function filterColumn($column, $method)
|
||||
{
|
||||
$params = func_get_args();
|
||||
$this->columnDef['filter'][$column] = ['method' => $method, 'parameters' => array_splice($params, 2)];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Order each given columns versus the given custom sql.
|
||||
*
|
||||
* @param array $columns
|
||||
* @param string $sql
|
||||
* @param array $bindings
|
||||
* @return $this
|
||||
*/
|
||||
public function orderColumns(array $columns, $sql, $bindings = [])
|
||||
{
|
||||
foreach ($columns as $column) {
|
||||
$this->orderColumn($column, str_replace(':column', $column, $sql), $bindings);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override default column ordering.
|
||||
*
|
||||
* @param string $column
|
||||
* @param string $sql
|
||||
* @param array $bindings
|
||||
* @return $this
|
||||
* @internal string $1 Special variable that returns the requested order direction of the column.
|
||||
*/
|
||||
public function orderColumn($column, $sql, $bindings = [])
|
||||
{
|
||||
$this->columnDef['order'][$column] = ['method' => 'orderByRaw', 'parameters' => [$sql, $bindings]];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set data output transformer.
|
||||
*
|
||||
* @param \League\Fractal\TransformerAbstract $transformer
|
||||
* @return $this
|
||||
*/
|
||||
public function setTransformer($transformer)
|
||||
{
|
||||
$this->transformer = $transformer;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set fractal serializer class.
|
||||
*
|
||||
* @param string $serializer
|
||||
* @return $this
|
||||
*/
|
||||
public function setSerializer($serializer)
|
||||
{
|
||||
$this->serializer = $serializer;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Organizes works.
|
||||
*
|
||||
* @param bool $mDataSupport
|
||||
* @param bool $orderFirst
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function make($mDataSupport = false, $orderFirst = false)
|
||||
{
|
||||
$this->totalRecords = $this->totalCount();
|
||||
|
||||
if ($this->totalRecords) {
|
||||
$this->orderRecords(! $orderFirst);
|
||||
$this->filterRecords();
|
||||
$this->orderRecords($orderFirst);
|
||||
$this->paginate();
|
||||
}
|
||||
|
||||
return $this->render($mDataSupport);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort records.
|
||||
*
|
||||
* @param boolean $skip
|
||||
* @return void
|
||||
*/
|
||||
public function orderRecords($skip)
|
||||
{
|
||||
if (! $skip) {
|
||||
$this->ordering();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform necessary filters.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function filterRecords()
|
||||
{
|
||||
if ($this->autoFilter && $this->request->isSearchable()) {
|
||||
$this->filtering();
|
||||
}
|
||||
|
||||
if (is_callable($this->filterCallback)) {
|
||||
call_user_func($this->filterCallback, $this->filterCallbackParameters);
|
||||
}
|
||||
|
||||
$this->columnSearch();
|
||||
$this->filteredRecords = $this->isFilterApplied ? $this->count() : $this->totalRecords;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply pagination.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function paginate()
|
||||
{
|
||||
if ($this->request->isPaginationable()) {
|
||||
$this->paging();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render json response.
|
||||
*
|
||||
* @param bool $object
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function render($object = false)
|
||||
{
|
||||
$output = array_merge([
|
||||
'draw' => (int) $this->request['draw'],
|
||||
'recordsTotal' => $this->totalRecords,
|
||||
'recordsFiltered' => $this->filteredRecords,
|
||||
], $this->appends);
|
||||
|
||||
if (isset($this->transformer)) {
|
||||
$fractal = app('datatables.fractal');
|
||||
|
||||
if ($this->serializer) {
|
||||
$fractal->setSerializer(new $this->serializer);
|
||||
}
|
||||
|
||||
//Get transformer reflection
|
||||
//Firs method parameter should be data/object to transform
|
||||
$reflection = new \ReflectionMethod($this->transformer, 'transform');
|
||||
$parameter = $reflection->getParameters()[0];
|
||||
|
||||
//If parameter is class assuming it requires object
|
||||
//Else just pass array by default
|
||||
if ($parameter->getClass()) {
|
||||
$resource = new Collection($this->results(), $this->createTransformer());
|
||||
} else {
|
||||
$resource = new Collection(
|
||||
$this->getProcessedData($object),
|
||||
$this->createTransformer()
|
||||
);
|
||||
}
|
||||
|
||||
$collection = $fractal->createData($resource)->toArray();
|
||||
$output['data'] = $collection['data'];
|
||||
} else {
|
||||
$output['data'] = Helper::transform($this->getProcessedData($object));
|
||||
}
|
||||
|
||||
if ($this->isDebugging()) {
|
||||
$output = $this->showDebugger($output);
|
||||
}
|
||||
|
||||
return new JsonResponse($output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get or create transformer instance.
|
||||
*
|
||||
* @return \League\Fractal\TransformerAbstract
|
||||
*/
|
||||
protected function createTransformer()
|
||||
{
|
||||
if ($this->transformer instanceof \League\Fractal\TransformerAbstract) {
|
||||
return $this->transformer;
|
||||
}
|
||||
|
||||
return new $this->transformer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get processed data
|
||||
*
|
||||
* @param bool|false $object
|
||||
* @return array
|
||||
*/
|
||||
private function getProcessedData($object = false)
|
||||
{
|
||||
$processor = new DataProcessor(
|
||||
$this->results(),
|
||||
$this->columnDef,
|
||||
$this->templates,
|
||||
$this->request['start']
|
||||
);
|
||||
|
||||
return $processor->process($object);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if app is in debug mode.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isDebugging()
|
||||
{
|
||||
return Config::get('app.debug', false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Append debug parameters on output.
|
||||
*
|
||||
* @param array $output
|
||||
* @return array
|
||||
*/
|
||||
public function showDebugger(array $output)
|
||||
{
|
||||
$output['queries'] = $this->connection->getQueryLog();
|
||||
$output['input'] = $this->request->all();
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update flags to disable global search
|
||||
*
|
||||
* @param \Closure $callback
|
||||
* @param mixed $parameters
|
||||
* @param bool $autoFilter
|
||||
*/
|
||||
public function overrideGlobalSearch(\Closure $callback, $parameters, $autoFilter = false)
|
||||
{
|
||||
$this->autoFilter = $autoFilter;
|
||||
$this->isFilterApplied = true;
|
||||
$this->filterCallback = $callback;
|
||||
$this->filterCallbackParameters = $parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get config is case insensitive status.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isCaseInsensitive()
|
||||
{
|
||||
return Config::get('datatables.search.case_insensitive', false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Append data on json response.
|
||||
*
|
||||
* @param mixed $key
|
||||
* @param mixed $value
|
||||
* @return $this
|
||||
*/
|
||||
public function with($key, $value = '')
|
||||
{
|
||||
if (is_array($key)) {
|
||||
$this->appends = $key;
|
||||
} elseif (is_callable($value)) {
|
||||
$this->appends[$key] = value($value);
|
||||
} else {
|
||||
$this->appends[$key] = value($value);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override default ordering method with a closure callback.
|
||||
*
|
||||
* @param \Closure $closure
|
||||
* @return $this
|
||||
*/
|
||||
public function order(\Closure $closure)
|
||||
{
|
||||
$this->orderCallback = $closure;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update list of columns that is not allowed for search/sort.
|
||||
*
|
||||
* @param array $blacklist
|
||||
* @return $this
|
||||
*/
|
||||
public function blacklist(array $blacklist)
|
||||
{
|
||||
$this->columnDef['blacklist'] = $blacklist;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update list of columns that is not allowed for search/sort.
|
||||
*
|
||||
* @param string|array $whitelist
|
||||
* @return $this
|
||||
*/
|
||||
public function whitelist($whitelist = '*')
|
||||
{
|
||||
$this->columnDef['whitelist'] = $whitelist;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set smart search config at runtime.
|
||||
*
|
||||
* @param bool $bool
|
||||
* @return $this
|
||||
*/
|
||||
public function smart($bool = true)
|
||||
{
|
||||
Config::set('datatables.search.smart', $bool);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if column is blacklisted.
|
||||
*
|
||||
* @param string $column
|
||||
* @return bool
|
||||
*/
|
||||
protected function isBlacklisted($column)
|
||||
{
|
||||
if (in_array($column, $this->columnDef['blacklist'])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($this->columnDef['whitelist'] === '*' || in_array($column, $this->columnDef['whitelist'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get column name to be use for filtering and sorting.
|
||||
*
|
||||
* @param integer $index
|
||||
* @param bool $wantsAlias
|
||||
* @return string
|
||||
*/
|
||||
protected function getColumnName($index, $wantsAlias = false)
|
||||
{
|
||||
$column = $this->request->columnName($index);
|
||||
|
||||
// DataTables is using make(false)
|
||||
if (is_numeric($column)) {
|
||||
$column = $this->getColumnNameByIndex($index);
|
||||
}
|
||||
|
||||
if (Str::contains(Str::upper($column), ' AS ')) {
|
||||
$column = $this->extractColumnName($column, $wantsAlias);
|
||||
}
|
||||
|
||||
return $column;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get column name by order column index.
|
||||
*
|
||||
* @param int $index
|
||||
* @return mixed
|
||||
*/
|
||||
protected function getColumnNameByIndex($index)
|
||||
{
|
||||
$name = isset($this->columns[$index]) && $this->columns[$index] <> '*' ? $this->columns[$index] : $this->getPrimaryKeyName();
|
||||
|
||||
return in_array($name, $this->extraColumns, true) ? $this->getPrimaryKeyName() : $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* If column name could not be resolved then use primary key.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getPrimaryKeyName()
|
||||
{
|
||||
if ($this->isEloquent()) {
|
||||
return $this->query->getModel()->getKeyName();
|
||||
}
|
||||
|
||||
return 'id';
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the engine used was eloquent.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isEloquent()
|
||||
{
|
||||
return $this->query_type === 'eloquent';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get column name from string.
|
||||
*
|
||||
* @param string $str
|
||||
* @param bool $wantsAlias
|
||||
* @return string
|
||||
*/
|
||||
protected function extractColumnName($str, $wantsAlias)
|
||||
{
|
||||
$matches = explode(' as ', Str::lower($str));
|
||||
|
||||
if (! empty($matches)) {
|
||||
if ($wantsAlias) {
|
||||
return array_pop($matches);
|
||||
} else {
|
||||
return array_shift($matches);
|
||||
}
|
||||
} elseif (strpos($str, '.')) {
|
||||
$array = explode('.', $str);
|
||||
|
||||
return array_pop($array);
|
||||
}
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the current sql language is based on oracle syntax.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isOracleSql()
|
||||
{
|
||||
return in_array($this->database, ['oracle', 'oci8']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set total records manually.
|
||||
*
|
||||
* @param int $total
|
||||
* @return $this
|
||||
*/
|
||||
public function setTotalRecords($total)
|
||||
{
|
||||
$this->totalRecords = $total;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
@@ -1,235 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\Datatables\Engines;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Str;
|
||||
use Yajra\Datatables\Request;
|
||||
|
||||
/**
|
||||
* Class CollectionEngine.
|
||||
*
|
||||
* @package Yajra\Datatables\Engines
|
||||
* @author Arjay Angeles <aqangeles@gmail.com>
|
||||
*/
|
||||
class CollectionEngine extends BaseEngine
|
||||
{
|
||||
/**
|
||||
* Collection object
|
||||
*
|
||||
* @var \Illuminate\Support\Collection
|
||||
*/
|
||||
public $collection;
|
||||
|
||||
/**
|
||||
* Collection object
|
||||
*
|
||||
* @var \Illuminate\Support\Collection
|
||||
*/
|
||||
public $original_collection;
|
||||
|
||||
/**
|
||||
* CollectionEngine constructor.
|
||||
*
|
||||
* @param \Illuminate\Support\Collection $collection
|
||||
* @param \Yajra\Datatables\Request $request
|
||||
*/
|
||||
public function __construct(Collection $collection, Request $request)
|
||||
{
|
||||
$this->request = $request;
|
||||
$this->collection = $collection;
|
||||
$this->original_collection = $collection;
|
||||
$this->columns = array_keys($this->serialize($collection->first()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize collection
|
||||
*
|
||||
* @param mixed $collection
|
||||
* @return mixed|null
|
||||
*/
|
||||
protected function serialize($collection)
|
||||
{
|
||||
return $collection instanceof Arrayable ? $collection->toArray() : (array) $collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set auto filter off and run your own filter.
|
||||
* Overrides global search.
|
||||
*
|
||||
* @param \Closure $callback
|
||||
* @param bool $globalSearch
|
||||
* @return $this
|
||||
*/
|
||||
public function filter(Closure $callback, $globalSearch = false)
|
||||
{
|
||||
$this->overrideGlobalSearch($callback, $this, $globalSearch);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append debug parameters on output.
|
||||
*
|
||||
* @param array $output
|
||||
* @return array
|
||||
*/
|
||||
public function showDebugger(array $output)
|
||||
{
|
||||
$output["input"] = $this->request->all();
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Count total items.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function totalCount()
|
||||
{
|
||||
return $this->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* Count results.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return $this->collection->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform sorting of columns.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function ordering()
|
||||
{
|
||||
if ($this->orderCallback) {
|
||||
call_user_func($this->orderCallback, $this);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($this->request->orderableColumns() as $orderable) {
|
||||
$column = $this->getColumnName($orderable['column']);
|
||||
$this->collection = $this->collection->sortBy(
|
||||
function ($row) use ($column) {
|
||||
$data = $this->serialize($row);
|
||||
|
||||
return Arr::get($data, $column);
|
||||
}
|
||||
);
|
||||
|
||||
if ($orderable['direction'] == 'desc') {
|
||||
$this->collection = $this->collection->reverse();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform global search.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function filtering()
|
||||
{
|
||||
$columns = $this->request['columns'];
|
||||
$this->collection = $this->collection->filter(
|
||||
function ($row) use ($columns) {
|
||||
$data = $this->serialize($row);
|
||||
$this->isFilterApplied = true;
|
||||
$found = [];
|
||||
|
||||
$keyword = $this->request->keyword();
|
||||
foreach ($this->request->searchableColumnIndex() as $index) {
|
||||
$column = $this->getColumnName($index);
|
||||
if (! $value = Arr::get($data, $column)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($this->isCaseInsensitive()) {
|
||||
$found[] = Str::contains(Str::lower($value), Str::lower($keyword));
|
||||
} else {
|
||||
$found[] = Str::contains($value, $keyword);
|
||||
}
|
||||
}
|
||||
|
||||
return in_array(true, $found);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform column search.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function columnSearch()
|
||||
{
|
||||
$columns = $this->request->get('columns');
|
||||
for ($i = 0, $c = count($columns); $i < $c; $i++) {
|
||||
if ($this->request->isColumnSearchable($i)) {
|
||||
$this->isFilterApplied = true;
|
||||
|
||||
$column = $this->getColumnName($i);
|
||||
$keyword = $this->request->columnKeyword($i);
|
||||
|
||||
$this->collection = $this->collection->filter(
|
||||
function ($row) use ($column, $keyword) {
|
||||
$data = $this->serialize($row);
|
||||
|
||||
$value = Arr::get($data, $column);
|
||||
|
||||
if ($this->isCaseInsensitive()) {
|
||||
return strpos(Str::lower($value), Str::lower($keyword)) !== false;
|
||||
} else {
|
||||
return strpos($value, $keyword) !== false;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform pagination.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function paging()
|
||||
{
|
||||
$this->collection = $this->collection->slice(
|
||||
$this->request['start'],
|
||||
(int) $this->request['length'] > 0 ? $this->request['length'] : 10
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get results.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function results()
|
||||
{
|
||||
return $this->collection->all();
|
||||
}
|
||||
|
||||
/**
|
||||
* Organizes works.
|
||||
*
|
||||
* @param bool $mDataSupport
|
||||
* @param bool $orderFirst
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function make($mDataSupport = false, $orderFirst = true)
|
||||
{
|
||||
return parent::make($mDataSupport, $orderFirst);
|
||||
}
|
||||
}
|
@@ -1,28 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\Datatables\Engines;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Yajra\Datatables\Request;
|
||||
|
||||
/**
|
||||
* Class EloquentEngine.
|
||||
*
|
||||
* @package Yajra\Datatables\Engines
|
||||
* @author Arjay Angeles <aqangeles@gmail.com>
|
||||
*/
|
||||
class EloquentEngine extends QueryBuilderEngine
|
||||
{
|
||||
/**
|
||||
* @param mixed $model
|
||||
* @param \Yajra\Datatables\Request $request
|
||||
*/
|
||||
public function __construct($model, Request $request)
|
||||
{
|
||||
$builder = $model instanceof Builder ? $model : $model->getQuery();
|
||||
parent::__construct($builder->getQuery(), $request);
|
||||
|
||||
$this->query = $builder;
|
||||
$this->query_type = 'eloquent';
|
||||
}
|
||||
}
|
@@ -1,535 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\Datatables\Engines;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasOne;
|
||||
use Illuminate\Database\Query\Builder;
|
||||
use Illuminate\Support\Str;
|
||||
use Yajra\Datatables\Helper;
|
||||
use Yajra\Datatables\Request;
|
||||
|
||||
/**
|
||||
* Class QueryBuilderEngine.
|
||||
*
|
||||
* @package Yajra\Datatables\Engines
|
||||
* @author Arjay Angeles <aqangeles@gmail.com>
|
||||
*/
|
||||
class QueryBuilderEngine extends BaseEngine
|
||||
{
|
||||
/**
|
||||
* @param \Illuminate\Database\Query\Builder $builder
|
||||
* @param \Yajra\Datatables\Request $request
|
||||
*/
|
||||
public function __construct(Builder $builder, Request $request)
|
||||
{
|
||||
$this->query = $builder;
|
||||
$this->init($request, $builder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize attributes.
|
||||
*
|
||||
* @param \Yajra\Datatables\Request $request
|
||||
* @param \Illuminate\Database\Query\Builder $builder
|
||||
* @param string $type
|
||||
*/
|
||||
protected function init($request, $builder, $type = 'builder')
|
||||
{
|
||||
$this->request = $request;
|
||||
$this->query_type = $type;
|
||||
$this->columns = $builder->columns;
|
||||
$this->connection = $builder->getConnection();
|
||||
$this->prefix = $this->connection->getTablePrefix();
|
||||
$this->database = $this->connection->getDriverName();
|
||||
if ($this->isDebugging()) {
|
||||
$this->connection->enableQueryLog();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set auto filter off and run your own filter.
|
||||
* Overrides global search
|
||||
*
|
||||
* @param \Closure $callback
|
||||
* @param bool $globalSearch
|
||||
* @return $this
|
||||
*/
|
||||
public function filter(Closure $callback, $globalSearch = false)
|
||||
{
|
||||
$this->overrideGlobalSearch($callback, $this->query, $globalSearch);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Organizes works
|
||||
*
|
||||
* @param bool $mDataSupport
|
||||
* @param bool $orderFirst
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function make($mDataSupport = false, $orderFirst = false)
|
||||
{
|
||||
return parent::make($mDataSupport, $orderFirst);
|
||||
}
|
||||
|
||||
/**
|
||||
* Count total items.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function totalCount()
|
||||
{
|
||||
return $this->totalRecords ? $this->totalRecords : $this->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* Counts current query.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
$myQuery = clone $this->query;
|
||||
// if its a normal query ( no union, having and distinct word )
|
||||
// replace the select with static text to improve performance
|
||||
if (! Str::contains(Str::lower($myQuery->toSql()), ['union', 'having', 'distinct', 'order by', 'group by'])) {
|
||||
$row_count = $this->wrap('row_count');
|
||||
$myQuery->select($this->connection->raw("'1' as {$row_count}"));
|
||||
}
|
||||
|
||||
return $this->connection->table($this->connection->raw('(' . $myQuery->toSql() . ') count_row_table'))
|
||||
->setBindings($myQuery->getBindings())->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap column with DB grammar.
|
||||
*
|
||||
* @param string $column
|
||||
* @return string
|
||||
*/
|
||||
protected function wrap($column) {
|
||||
return $this->connection->getQueryGrammar()->wrap($column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform global search.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function filtering()
|
||||
{
|
||||
$this->query->where(
|
||||
function ($query) {
|
||||
$globalKeyword = $this->request->keyword();
|
||||
$queryBuilder = $this->getQueryBuilder($query);
|
||||
|
||||
foreach ($this->request->searchableColumnIndex() as $index) {
|
||||
$columnName = $this->getColumnName($index);
|
||||
if ($this->isBlacklisted($columnName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// check if custom column filtering is applied
|
||||
if (isset($this->columnDef['filter'][$columnName])) {
|
||||
$columnDef = $this->columnDef['filter'][$columnName];
|
||||
// check if global search should be applied for the specific column
|
||||
$applyGlobalSearch = count($columnDef['parameters']) == 0 || end($columnDef['parameters']) !== false;
|
||||
if (! $applyGlobalSearch) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($columnDef['method'] instanceof Closure) {
|
||||
$whereQuery = $queryBuilder->newQuery();
|
||||
call_user_func_array($columnDef['method'], [$whereQuery, $globalKeyword]);
|
||||
$queryBuilder->addNestedWhereQuery($whereQuery, 'or');
|
||||
} else {
|
||||
$this->compileColumnQuery(
|
||||
$queryBuilder,
|
||||
Helper::getOrMethod($columnDef['method']),
|
||||
$columnDef['parameters'],
|
||||
$columnName,
|
||||
$globalKeyword
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if (count(explode('.', $columnName)) > 1) {
|
||||
$eagerLoads = $this->getEagerLoads();
|
||||
$parts = explode('.', $columnName);
|
||||
$relationColumn = array_pop($parts);
|
||||
$relation = implode('.', $parts);
|
||||
if (in_array($relation, $eagerLoads)) {
|
||||
$this->compileRelationSearch(
|
||||
$queryBuilder,
|
||||
$relation,
|
||||
$relationColumn,
|
||||
$globalKeyword
|
||||
);
|
||||
} else {
|
||||
$this->compileQuerySearch($queryBuilder, $columnName, $globalKeyword);
|
||||
}
|
||||
} else {
|
||||
$this->compileQuerySearch($queryBuilder, $columnName, $globalKeyword);
|
||||
}
|
||||
}
|
||||
|
||||
$this->isFilterApplied = true;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform filter column on selected field.
|
||||
*
|
||||
* @param mixed $query
|
||||
* @param string|Closure $method
|
||||
* @param mixed $parameters
|
||||
* @param string $column
|
||||
* @param string $keyword
|
||||
*/
|
||||
protected function compileColumnQuery($query, $method, $parameters, $column, $keyword)
|
||||
{
|
||||
if (method_exists($query, $method)
|
||||
&& count($parameters) <= with(new \ReflectionMethod($query, $method))->getNumberOfParameters()
|
||||
) {
|
||||
if (Str::contains(Str::lower($method), 'raw')
|
||||
|| Str::contains(Str::lower($method), 'exists')
|
||||
) {
|
||||
call_user_func_array(
|
||||
[$query, $method],
|
||||
$this->parameterize($parameters, $keyword)
|
||||
);
|
||||
} else {
|
||||
call_user_func_array(
|
||||
[$query, $method],
|
||||
$this->parameterize($column, $parameters, $keyword)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build Query Builder Parameters.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function parameterize()
|
||||
{
|
||||
$args = func_get_args();
|
||||
$keyword = count($args) > 2 ? $args[2] : $args[1];
|
||||
$parameters = Helper::buildParameters($args);
|
||||
$parameters = Helper::replacePatternWithKeyword($parameters, $keyword, '$1');
|
||||
|
||||
return $parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get eager loads keys if eloquent.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getEagerLoads()
|
||||
{
|
||||
if ($this->query_type == 'eloquent') {
|
||||
return array_keys($this->query->getEagerLoads());
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Add relation query on global search.
|
||||
*
|
||||
* @param mixed $query
|
||||
* @param string $relation
|
||||
* @param string $column
|
||||
* @param string $keyword
|
||||
*/
|
||||
protected function compileRelationSearch($query, $relation, $column, $keyword)
|
||||
{
|
||||
$myQuery = clone $this->query;
|
||||
$myQuery->orWhereHas($relation, function ($builder) use ($column, $keyword, $query) {
|
||||
$builder->select($this->connection->raw('count(1)'));
|
||||
$this->compileQuerySearch($builder, $column, $keyword, '');
|
||||
$builder = "({$builder->toSql()}) >= 1";
|
||||
|
||||
$query->orWhereRaw($builder, [$keyword]);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile query builder where clause depending on configurations.
|
||||
*
|
||||
* @param mixed $query
|
||||
* @param string $column
|
||||
* @param string $keyword
|
||||
* @param string $relation
|
||||
*/
|
||||
protected function compileQuerySearch($query, $column, $keyword, $relation = 'or')
|
||||
{
|
||||
$column = strstr($column, '(') ? $this->connection->raw($column) : $column;
|
||||
$column = $this->castColumn($column);
|
||||
$sql = $column . ' LIKE ?';
|
||||
|
||||
if ($this->isCaseInsensitive()) {
|
||||
$sql = 'LOWER(' . $column . ') LIKE ?';
|
||||
$keyword = Str::lower($keyword);
|
||||
}
|
||||
|
||||
if ($this->isWildcard()) {
|
||||
$keyword = $this->wildcardLikeString($keyword);
|
||||
}
|
||||
|
||||
if ($this->isSmartSearch()) {
|
||||
$keyword = "%$keyword%";
|
||||
}
|
||||
|
||||
$query->{$relation .'WhereRaw'}($sql, [$keyword]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap a column and cast in pgsql.
|
||||
*
|
||||
* @param string $column
|
||||
* @return string
|
||||
*/
|
||||
public function castColumn($column)
|
||||
{
|
||||
$column = $this->wrap($column);
|
||||
if ($this->database === 'pgsql') {
|
||||
$column = 'CAST(' . $column . ' as TEXT)';
|
||||
} elseif ($this->database === 'firebird') {
|
||||
$column = 'CAST(' . $column . ' as VARCHAR(255))';
|
||||
}
|
||||
|
||||
return $column;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform column search.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function columnSearch()
|
||||
{
|
||||
$columns = $this->request->get('columns', []);
|
||||
|
||||
foreach ($columns as $index => $column) {
|
||||
if (! $this->request->isColumnSearchable($index)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$column = $this->getColumnName($index);
|
||||
|
||||
if (isset($this->columnDef['filter'][$column])) {
|
||||
$columnDef = $this->columnDef['filter'][$column];
|
||||
// get a raw keyword (without wildcards)
|
||||
$keyword = $this->getSearchKeyword($index, true);
|
||||
$builder = $this->getQueryBuilder();
|
||||
|
||||
if ($columnDef['method'] instanceof Closure) {
|
||||
$whereQuery = $builder->newQuery();
|
||||
call_user_func_array($columnDef['method'], [$whereQuery, $keyword]);
|
||||
$builder->addNestedWhereQuery($whereQuery);
|
||||
} else {
|
||||
$this->compileColumnQuery(
|
||||
$builder,
|
||||
$columnDef['method'],
|
||||
$columnDef['parameters'],
|
||||
$column,
|
||||
$keyword
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if (count(explode('.', $column)) > 1) {
|
||||
$eagerLoads = $this->getEagerLoads();
|
||||
$parts = explode('.', $column);
|
||||
$relationColumn = array_pop($parts);
|
||||
$relation = implode('.', $parts);
|
||||
if (in_array($relation, $eagerLoads)) {
|
||||
$column = $this->joinEagerLoadedColumn($relation, $relationColumn);
|
||||
}
|
||||
}
|
||||
|
||||
$keyword = $this->getSearchKeyword($index);
|
||||
$this->compileColumnSearch($index, $column, $keyword);
|
||||
}
|
||||
|
||||
$this->isFilterApplied = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get proper keyword to use for search.
|
||||
*
|
||||
* @param int $i
|
||||
* @param bool $raw
|
||||
* @return string
|
||||
*/
|
||||
private function getSearchKeyword($i, $raw = false)
|
||||
{
|
||||
$keyword = $this->request->columnKeyword($i);
|
||||
if ($raw || $this->request->isRegex($i)) {
|
||||
return $keyword;
|
||||
}
|
||||
|
||||
return $this->setupKeyword($keyword);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile queries for column search.
|
||||
*
|
||||
* @param int $i
|
||||
* @param mixed $column
|
||||
* @param string $keyword
|
||||
*/
|
||||
protected function compileColumnSearch($i, $column, $keyword)
|
||||
{
|
||||
if ($this->request->isRegex($i)) {
|
||||
$column = strstr($column, '(') ? $this->connection->raw($column) : $column;
|
||||
$this->regexColumnSearch($column, $keyword);
|
||||
} else {
|
||||
$this->compileQuerySearch($this->query, $column, $keyword, '');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile regex query column search.
|
||||
*
|
||||
* @param mixed $column
|
||||
* @param string $keyword
|
||||
*/
|
||||
protected function regexColumnSearch($column, $keyword)
|
||||
{
|
||||
if ($this->isOracleSql()) {
|
||||
$sql = ! $this->isCaseInsensitive() ? 'REGEXP_LIKE( ' . $column . ' , ? )' : 'REGEXP_LIKE( LOWER(' . $column . ') , ?, \'i\' )';
|
||||
$this->query->whereRaw($sql, [$keyword]);
|
||||
} else {
|
||||
$sql = ! $this->isCaseInsensitive() ? $column . ' REGEXP ?' : 'LOWER(' . $column . ') REGEXP ?';
|
||||
$this->query->whereRaw($sql, [Str::lower($keyword)]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform sorting of columns.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function ordering()
|
||||
{
|
||||
if ($this->orderCallback) {
|
||||
call_user_func($this->orderCallback, $this->getQueryBuilder());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($this->request->orderableColumns() as $orderable) {
|
||||
$column = $this->getColumnName($orderable['column'], true);
|
||||
|
||||
if ($this->isBlacklisted($column)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isset($this->columnDef['order'][$column])) {
|
||||
$method = $this->columnDef['order'][$column]['method'];
|
||||
$parameters = $this->columnDef['order'][$column]['parameters'];
|
||||
$this->compileColumnQuery(
|
||||
$this->getQueryBuilder(),
|
||||
$method,
|
||||
$parameters,
|
||||
$column,
|
||||
$orderable['direction']
|
||||
);
|
||||
} else {
|
||||
if (count(explode('.', $column)) > 1) {
|
||||
$eagerLoads = $this->getEagerLoads();
|
||||
$parts = explode('.', $column);
|
||||
$relationColumn = array_pop($parts);
|
||||
$relation = implode('.', $parts);
|
||||
|
||||
if (in_array($relation, $eagerLoads)) {
|
||||
$column = $this->joinEagerLoadedColumn($relation, $relationColumn);
|
||||
}
|
||||
}
|
||||
|
||||
$this->getQueryBuilder()->orderBy($column, $orderable['direction']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Join eager loaded relation and get the related column name.
|
||||
*
|
||||
* @param string $relation
|
||||
* @param string $relationColumn
|
||||
* @return string
|
||||
*/
|
||||
protected function joinEagerLoadedColumn($relation, $relationColumn)
|
||||
{
|
||||
$joins = [];
|
||||
foreach ((array) $this->getQueryBuilder()->joins as $key => $join) {
|
||||
$joins[] = $join->table;
|
||||
}
|
||||
|
||||
$model = $this->query->getRelation($relation);
|
||||
if ($model instanceof BelongsToMany) {
|
||||
$pivot = $model->getTable();
|
||||
$pivotPK = $model->getForeignKey();
|
||||
$pivotFK = $model->getQualifiedParentKeyName();
|
||||
|
||||
if (! in_array($pivot, $joins)) {
|
||||
$this->getQueryBuilder()->leftJoin($pivot, $pivotPK, '=', $pivotFK);
|
||||
}
|
||||
|
||||
$related = $model->getRelated();
|
||||
$table = $related->getTable();
|
||||
$tablePK = $related->getForeignKey();
|
||||
$tableFK = $related->getQualifiedKeyName();
|
||||
|
||||
if (! in_array($table, $joins)) {
|
||||
$this->getQueryBuilder()->leftJoin($table, $pivot . '.' . $tablePK, '=', $tableFK);
|
||||
}
|
||||
} else {
|
||||
$table = $model->getRelated()->getTable();
|
||||
if ($model instanceof HasOne) {
|
||||
$foreign = $model->getForeignKey();
|
||||
$other = $model->getQualifiedParentKeyName();
|
||||
} else {
|
||||
$foreign = $model->getQualifiedForeignKey();
|
||||
$other = $model->getQualifiedOtherKeyName();
|
||||
}
|
||||
|
||||
if (! in_array($table, $joins)) {
|
||||
$this->getQueryBuilder()->leftJoin($table, $foreign, '=', $other);
|
||||
}
|
||||
}
|
||||
|
||||
$column = $table . '.' . $relationColumn;
|
||||
|
||||
return $column;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform pagination
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function paging()
|
||||
{
|
||||
$this->query->skip($this->request['start'])
|
||||
->take((int) $this->request['length'] > 0 ? $this->request['length'] : 10);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get results
|
||||
*
|
||||
* @return array|static[]
|
||||
*/
|
||||
public function results()
|
||||
{
|
||||
return $this->query->get();
|
||||
}
|
||||
}
|
7
vendor/yajra/laravel-datatables-oracle/src/Exceptions/Exception.php
vendored
Normal file
7
vendor/yajra/laravel-datatables-oracle/src/Exceptions/Exception.php
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\DataTables\Exceptions;
|
||||
|
||||
class Exception extends \Exception
|
||||
{
|
||||
}
|
26
vendor/yajra/laravel-datatables-oracle/src/Facades/DataTables.php
vendored
Normal file
26
vendor/yajra/laravel-datatables-oracle/src/Facades/DataTables.php
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\DataTables\Facades;
|
||||
|
||||
use Illuminate\Support\Facades\Facade;
|
||||
|
||||
/**
|
||||
* @mixin \Yajra\DataTables\DataTables
|
||||
* @method static \Yajra\DataTables\EloquentDatatable eloquent($builder)
|
||||
* @method static \Yajra\DataTables\QueryDataTable query($builder)
|
||||
* @method static \Yajra\DataTables\CollectionDataTable collection($collection)
|
||||
*
|
||||
* @see \Yajra\DataTables\DataTables
|
||||
*/
|
||||
class DataTables extends Facade
|
||||
{
|
||||
/**
|
||||
* Get the registered name of the component.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function getFacadeAccessor()
|
||||
{
|
||||
return 'datatables';
|
||||
}
|
||||
}
|
@@ -1,24 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\Datatables\Facades;
|
||||
|
||||
use Illuminate\Support\Facades\Facade;
|
||||
|
||||
/**
|
||||
* Class Datatables.
|
||||
*
|
||||
* @package Yajra\Datatables\Facades
|
||||
* @author Arjay Angeles <aqangeles@gmail.com>
|
||||
*/
|
||||
class Datatables extends Facade
|
||||
{
|
||||
/**
|
||||
* Get the registered name of the component.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function getFacadeAccessor()
|
||||
{
|
||||
return 'datatables';
|
||||
}
|
||||
}
|
@@ -1,208 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\Datatables\Generators;
|
||||
|
||||
use Illuminate\Console\GeneratorCommand;
|
||||
use Illuminate\Support\Str;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
|
||||
/**
|
||||
* Class DataTablesMakeCommand.
|
||||
*
|
||||
* @package Yajra\Datatables\Generators
|
||||
* @author Arjay Angeles <aqangeles@gmail.com>
|
||||
*/
|
||||
class DataTablesMakeCommand extends GeneratorCommand
|
||||
{
|
||||
/**
|
||||
* The console command name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $name = 'datatables:make';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Create a new DataTable service class.';
|
||||
|
||||
/**
|
||||
* The type of class being generated.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $type = 'DataTable';
|
||||
|
||||
/**
|
||||
* The model class to be used by dataTable.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $model;
|
||||
|
||||
/**
|
||||
* DataTable export filename.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $filename;
|
||||
|
||||
/**
|
||||
* Build the class with the given name.
|
||||
*
|
||||
* @param string $name
|
||||
* @return string
|
||||
*/
|
||||
protected function buildClass($name)
|
||||
{
|
||||
$stub = $this->files->get($this->getStub());
|
||||
$stub = $this->replaceNamespace($stub, $name)->replaceClass($stub, $name);
|
||||
|
||||
return $this->replaceModelImport($stub)->replaceModel($stub)->replaceFilename($stub);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the stub file for the generator.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getStub()
|
||||
{
|
||||
return __DIR__ . '/stubs/datatables.stub';
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace model name.
|
||||
*
|
||||
* @param string $stub
|
||||
* @return mixed
|
||||
*/
|
||||
protected function replaceModel(&$stub)
|
||||
{
|
||||
$model = explode('\\', $this->model);
|
||||
$model = array_pop($model);
|
||||
$stub = str_replace('ModelName', $model, $stub);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace model import.
|
||||
*
|
||||
* @param string $stub
|
||||
* @return $this
|
||||
*/
|
||||
protected function replaceModelImport(&$stub)
|
||||
{
|
||||
$stub = str_replace(
|
||||
'DummyModel', str_replace('\\\\', '\\', $this->model), $stub
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace the filename.
|
||||
*
|
||||
* @param string $stub
|
||||
* @return string
|
||||
*/
|
||||
protected function replaceFilename(&$stub)
|
||||
{
|
||||
$stub = str_replace(
|
||||
'DummyFilename', $this->filename, $stub
|
||||
);
|
||||
|
||||
return $stub;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the console command options.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getOptions()
|
||||
{
|
||||
return [
|
||||
['model', null, InputOption::VALUE_NONE, 'Use the provided name as the model.', null],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the class already exists.
|
||||
*
|
||||
* @param string $rawName
|
||||
* @return bool
|
||||
*/
|
||||
protected function alreadyExists($rawName)
|
||||
{
|
||||
$name = $this->parseName($rawName);
|
||||
|
||||
$this->setModel($rawName);
|
||||
$this->setFilename($rawName);
|
||||
|
||||
return $this->files->exists($this->getPath($name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the name and format according to the root namespace.
|
||||
*
|
||||
* @param string $name
|
||||
* @return string
|
||||
*/
|
||||
protected function parseName($name)
|
||||
{
|
||||
$rootNamespace = $this->laravel->getNamespace();
|
||||
|
||||
if (Str::startsWith($name, $rootNamespace)) {
|
||||
return $name;
|
||||
}
|
||||
|
||||
if (Str::contains($name, '/')) {
|
||||
$name = str_replace('/', '\\', $name);
|
||||
}
|
||||
|
||||
if (! Str::contains(Str::lower($name), 'datatable')) {
|
||||
$name .= 'DataTable';
|
||||
}
|
||||
|
||||
return $this->parseName($this->getDefaultNamespace(trim($rootNamespace, '\\')) . '\\' . $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default namespace for the class.
|
||||
*
|
||||
* @param string $rootNamespace
|
||||
* @return string
|
||||
*/
|
||||
protected function getDefaultNamespace($rootNamespace)
|
||||
{
|
||||
return $rootNamespace . "\\" . $this->laravel['config']->get('datatables.namespace.base', 'DataTables');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the model to be used.
|
||||
*
|
||||
* @param string $name
|
||||
*/
|
||||
protected function setModel($name)
|
||||
{
|
||||
$rootNamespace = $this->laravel->getNamespace();
|
||||
$modelNamespace = $this->laravel['config']->get('datatables.namespace.model');
|
||||
$this->model = $this->option('model')
|
||||
? $rootNamespace . "\\" . ($modelNamespace ? $modelNamespace . "\\" : "") . $name
|
||||
: $rootNamespace . "\\User";
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the filename for export.
|
||||
*
|
||||
* @param string $name
|
||||
*/
|
||||
protected function setFilename($name)
|
||||
{
|
||||
$this->filename = Str::lower(Str::plural($name));
|
||||
}
|
||||
}
|
@@ -1,56 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\Datatables\Generators;
|
||||
|
||||
use Illuminate\Console\GeneratorCommand;
|
||||
|
||||
/**
|
||||
* Class DataTablesScopeCommand.
|
||||
*
|
||||
* @package Yajra\Datatables\Generators
|
||||
* @author Arjay Angeles <aqangeles@gmail.com>
|
||||
*/
|
||||
class DataTablesScopeCommand extends GeneratorCommand
|
||||
{
|
||||
/**
|
||||
* The console command name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $name = 'datatables:scope';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Create a new DataTable Scope class.';
|
||||
|
||||
/**
|
||||
* The type of class being generated.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $type = 'DataTable Scope';
|
||||
|
||||
/**
|
||||
* Get the default namespace for the class.
|
||||
*
|
||||
* @param string $rootNamespace
|
||||
* @return string
|
||||
*/
|
||||
protected function getDefaultNamespace($rootNamespace)
|
||||
{
|
||||
return $rootNamespace . '\DataTables\Scopes';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the stub file for the generator.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getStub()
|
||||
{
|
||||
return __DIR__ . '/stubs/scopes.stub';
|
||||
}
|
||||
}
|
@@ -1,73 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace DummyNamespace;
|
||||
|
||||
use DummyModel;
|
||||
use Yajra\Datatables\Services\DataTable;
|
||||
|
||||
class DummyClass extends DataTable
|
||||
{
|
||||
/**
|
||||
* Display ajax response.
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function ajax()
|
||||
{
|
||||
return $this->datatables
|
||||
->eloquent($this->query())
|
||||
->addColumn('action', 'path.to.action.view')
|
||||
->make(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the query object to be processed by dataTables.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Query\Builder|\Illuminate\Support\Collection
|
||||
*/
|
||||
public function query()
|
||||
{
|
||||
$query = ModelName::query();
|
||||
|
||||
return $this->applyScopes($query);
|
||||
}
|
||||
|
||||
/**
|
||||
* Optional method if you want to use html builder.
|
||||
*
|
||||
* @return \Yajra\Datatables\Html\Builder
|
||||
*/
|
||||
public function html()
|
||||
{
|
||||
return $this->builder()
|
||||
->columns($this->getColumns())
|
||||
->ajax('')
|
||||
->addAction(['width' => '80px'])
|
||||
->parameters($this->getBuilderParameters());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get columns.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getColumns()
|
||||
{
|
||||
return [
|
||||
'id',
|
||||
// add your columns
|
||||
'created_at',
|
||||
'updated_at',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get filename for export.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function filename()
|
||||
{
|
||||
return 'DummyFilename_' . time();
|
||||
}
|
||||
}
|
@@ -1,19 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace DummyNamespace;
|
||||
|
||||
use Yajra\Datatables\Contracts\DataTableScopeContract;
|
||||
|
||||
class DummyClass implements DataTableScopeContract
|
||||
{
|
||||
/**
|
||||
* Apply a query scope.
|
||||
*
|
||||
* @param \Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder $query
|
||||
* @return mixed
|
||||
*/
|
||||
public function apply($query)
|
||||
{
|
||||
// return $query->where('id', 1);
|
||||
}
|
||||
}
|
@@ -1,620 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\Datatables\Html;
|
||||
|
||||
use Collective\Html\FormBuilder;
|
||||
use Collective\Html\HtmlBuilder;
|
||||
use Illuminate\Contracts\Config\Repository;
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
use Illuminate\Routing\UrlGenerator;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Config;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
/**
|
||||
* Class Builder.
|
||||
*
|
||||
* @package Yajra\Datatables\Html
|
||||
* @author Arjay Angeles <aqangeles@gmail.com>
|
||||
*/
|
||||
class Builder
|
||||
{
|
||||
/**
|
||||
* @var Collection
|
||||
*/
|
||||
public $collection;
|
||||
|
||||
/**
|
||||
* @var Repository
|
||||
*/
|
||||
public $config;
|
||||
|
||||
/**
|
||||
* @var Factory
|
||||
*/
|
||||
public $view;
|
||||
|
||||
/**
|
||||
* @var HtmlBuilder
|
||||
*/
|
||||
public $html;
|
||||
|
||||
/**
|
||||
* @var UrlGenerator
|
||||
*/
|
||||
public $url;
|
||||
|
||||
/**
|
||||
* @var FormBuilder
|
||||
*/
|
||||
public $form;
|
||||
|
||||
/**
|
||||
* @var string|array
|
||||
*/
|
||||
protected $ajax = '';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $tableAttributes = ['class' => 'table', 'id' => 'dataTableBuilder'];
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $template = '';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $attributes = [];
|
||||
|
||||
/**
|
||||
* Lists of valid DataTables Callbacks.
|
||||
*
|
||||
* @link https://datatables.net/reference/option/.
|
||||
* @var array
|
||||
*/
|
||||
protected $validCallbacks = [
|
||||
'createdRow',
|
||||
'drawCallback',
|
||||
'footerCallback',
|
||||
'formatNumber',
|
||||
'headerCallback',
|
||||
'infoCallback',
|
||||
'initComplete',
|
||||
'preDrawCallback',
|
||||
'rowCallback',
|
||||
'stateLoadCallback',
|
||||
'stateLoaded',
|
||||
'stateLoadParams',
|
||||
'stateSaveCallback',
|
||||
'stateSaveParams',
|
||||
];
|
||||
|
||||
/**
|
||||
* @param Repository $config
|
||||
* @param Factory $view
|
||||
* @param HtmlBuilder $html
|
||||
* @param UrlGenerator $url
|
||||
* @param FormBuilder $form
|
||||
*/
|
||||
public function __construct(
|
||||
Repository $config,
|
||||
Factory $view,
|
||||
HtmlBuilder $html,
|
||||
UrlGenerator $url,
|
||||
FormBuilder $form
|
||||
) {
|
||||
$this->config = $config;
|
||||
$this->view = $view;
|
||||
$this->html = $html;
|
||||
$this->url = $url;
|
||||
$this->collection = new Collection;
|
||||
$this->form = $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate DataTable javascript.
|
||||
*
|
||||
* @param null $script
|
||||
* @param array $attributes
|
||||
* @return string
|
||||
*/
|
||||
public function scripts($script = null, array $attributes = ['type' => 'text/javascript'])
|
||||
{
|
||||
$script = $script ?: $this->generateScripts();
|
||||
|
||||
return '<script' . $this->html->attributes($attributes) . '>' . $script . '</script>' . PHP_EOL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get generated raw scripts.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function generateScripts()
|
||||
{
|
||||
$args = array_merge(
|
||||
$this->attributes, [
|
||||
'ajax' => $this->ajax,
|
||||
'columns' => $this->collection->toArray(),
|
||||
]
|
||||
);
|
||||
|
||||
$parameters = $this->parameterize($args);
|
||||
|
||||
return sprintf(
|
||||
$this->template(),
|
||||
$this->tableAttributes['id'], $parameters
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate DataTables js parameters.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @return string
|
||||
*/
|
||||
public function parameterize($attributes = [])
|
||||
{
|
||||
$parameters = (new Parameters($attributes))->toArray();
|
||||
|
||||
list($ajaxDataFunction, $parameters) = $this->encodeAjaxDataFunction($parameters);
|
||||
list($columnFunctions, $parameters) = $this->encodeColumnFunctions($parameters);
|
||||
list($callbackFunctions, $parameters) = $this->encodeCallbackFunctions($parameters);
|
||||
|
||||
$json = json_encode($parameters);
|
||||
|
||||
$json = $this->decodeAjaxDataFunction($ajaxDataFunction, $json);
|
||||
$json = $this->decodeColumnFunctions($columnFunctions, $json);
|
||||
$json = $this->decodeCallbackFunctions($callbackFunctions, $json);
|
||||
|
||||
return $json;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode ajax data function param.
|
||||
*
|
||||
* @param array $parameters
|
||||
* @return mixed
|
||||
*/
|
||||
protected function encodeAjaxDataFunction($parameters)
|
||||
{
|
||||
$ajaxData = '';
|
||||
if (isset($parameters['ajax']['data'])) {
|
||||
$ajaxData = $parameters['ajax']['data'];
|
||||
$parameters['ajax']['data'] = "#ajax_data#";
|
||||
}
|
||||
|
||||
return [$ajaxData, $parameters];
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode columns render function.
|
||||
*
|
||||
* @param array $parameters
|
||||
* @return array
|
||||
*/
|
||||
protected function encodeColumnFunctions(array $parameters)
|
||||
{
|
||||
$columnFunctions = [];
|
||||
foreach ($parameters['columns'] as $i => $column) {
|
||||
unset($parameters['columns'][$i]['exportable']);
|
||||
unset($parameters['columns'][$i]['printable']);
|
||||
unset($parameters['columns'][$i]['footer']);
|
||||
|
||||
if (isset($column['render'])) {
|
||||
$columnFunctions[$i] = $column['render'];
|
||||
$parameters['columns'][$i]['render'] = "#column_function.{$i}#";
|
||||
}
|
||||
}
|
||||
|
||||
return [$columnFunctions, $parameters];
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode DataTables callbacks function.
|
||||
*
|
||||
* @param array $parameters
|
||||
* @return array
|
||||
*/
|
||||
protected function encodeCallbackFunctions(array $parameters)
|
||||
{
|
||||
$callbackFunctions = [];
|
||||
foreach ($parameters as $key => $callback) {
|
||||
if (in_array($key, $this->validCallbacks)) {
|
||||
$callbackFunctions[$key] = $this->compileCallback($callback);
|
||||
$parameters[$key] = "#callback_function.{$key}#";
|
||||
}
|
||||
}
|
||||
|
||||
return [$callbackFunctions, $parameters];
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile DataTable callback value.
|
||||
*
|
||||
* @param mixed $callback
|
||||
* @return mixed|string
|
||||
*/
|
||||
private function compileCallback($callback)
|
||||
{
|
||||
if (is_callable($callback)) {
|
||||
return value($callback);
|
||||
} elseif ($this->view->exists($callback)) {
|
||||
return $this->view->make($callback)->render();
|
||||
}
|
||||
|
||||
return $callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode ajax data method.
|
||||
*
|
||||
* @param string $function
|
||||
* @param string $json
|
||||
* @return string
|
||||
*/
|
||||
protected function decodeAjaxDataFunction($function, $json)
|
||||
{
|
||||
return str_replace("\"#ajax_data#\"", $function, $json);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode columns render functions.
|
||||
*
|
||||
* @param array $columnFunctions
|
||||
* @param string $json
|
||||
* @return string
|
||||
*/
|
||||
protected function decodeColumnFunctions(array $columnFunctions, $json)
|
||||
{
|
||||
foreach ($columnFunctions as $i => $function) {
|
||||
$json = str_replace("\"#column_function.{$i}#\"", $function, $json);
|
||||
}
|
||||
|
||||
return $json;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode DataTables callbacks function.
|
||||
*
|
||||
* @param array $callbackFunctions
|
||||
* @param string $json
|
||||
* @return string
|
||||
*/
|
||||
protected function decodeCallbackFunctions(array $callbackFunctions, $json)
|
||||
{
|
||||
foreach ($callbackFunctions as $i => $function) {
|
||||
$json = str_replace("\"#callback_function.{$i}#\"", $function, $json);
|
||||
}
|
||||
|
||||
return $json;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get javascript template to use.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function template()
|
||||
{
|
||||
return $this->view->make(
|
||||
$this->template ?: $this->config->get('datatables.script_template', 'datatables::script')
|
||||
)->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets HTML table attribute(s).
|
||||
*
|
||||
* @param string|array $attribute
|
||||
* @param mixed $value
|
||||
* @return $this
|
||||
*/
|
||||
public function setTableAttribute($attribute, $value = null)
|
||||
{
|
||||
if (is_array($attribute)) {
|
||||
$this->setTableAttributes($attribute);
|
||||
} else {
|
||||
$this->tableAttributes[$attribute] = $value;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets multiple HTML table attributes at once.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @return $this
|
||||
*/
|
||||
public function setTableAttributes(array $attributes)
|
||||
{
|
||||
foreach ($attributes as $attribute => $value) {
|
||||
$this->setTableAttribute($attribute, $value);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves HTML table attribute value.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @return mixed
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getTableAttribute($attribute)
|
||||
{
|
||||
if (! array_key_exists($attribute, $this->tableAttributes)) {
|
||||
throw new \Exception("Table attribute '{$attribute}' does not exist.");
|
||||
}
|
||||
|
||||
return $this->tableAttributes[$attribute];
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a column in collection using attributes.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @return $this
|
||||
*/
|
||||
public function addColumn(array $attributes)
|
||||
{
|
||||
$this->collection->push(new Column($attributes));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a Column object in collection.
|
||||
*
|
||||
* @param \Yajra\Datatables\Html\Column $column
|
||||
* @return $this
|
||||
*/
|
||||
public function add(Column $column)
|
||||
{
|
||||
$this->collection->push($column);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set datatables columns from array definition.
|
||||
*
|
||||
* @param array $columns
|
||||
* @return $this
|
||||
*/
|
||||
public function columns(array $columns)
|
||||
{
|
||||
foreach ($columns as $key => $value) {
|
||||
if (! is_a($value, Column::class)) {
|
||||
if (is_array($value)) {
|
||||
$attributes = array_merge(['name' => $key, 'data' => $key], $this->setTitle($key, $value));
|
||||
} else {
|
||||
$attributes = [
|
||||
'name' => $value,
|
||||
'data' => $value,
|
||||
'title' => $this->getQualifiedTitle($value),
|
||||
];
|
||||
}
|
||||
|
||||
$this->collection->push(new Column($attributes));
|
||||
} else {
|
||||
$this->collection->push($value);
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set title attribute of an array if not set.
|
||||
*
|
||||
* @param string $title
|
||||
* @param array $attributes
|
||||
* @return array
|
||||
*/
|
||||
public function setTitle($title, array $attributes)
|
||||
{
|
||||
if (! isset($attributes['title'])) {
|
||||
$attributes['title'] = $this->getQualifiedTitle($title);
|
||||
}
|
||||
|
||||
return $attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert string into a readable title.
|
||||
*
|
||||
* @param string $title
|
||||
* @return string
|
||||
*/
|
||||
public function getQualifiedTitle($title)
|
||||
{
|
||||
return Str::title(str_replace(['.', '_'], ' ', Str::snake($title)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a checkbox column.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @return $this
|
||||
*/
|
||||
public function addCheckbox(array $attributes = [])
|
||||
{
|
||||
$attributes = array_merge([
|
||||
'defaultContent' => '<input type="checkbox" ' . $this->html->attributes($attributes) . '/>',
|
||||
'title' => $this->form->checkbox('', '', false, ['id' => 'dataTablesCheckbox']),
|
||||
'data' => 'checkbox',
|
||||
'name' => 'checkbox',
|
||||
'orderable' => false,
|
||||
'searchable' => false,
|
||||
'exportable' => false,
|
||||
'printable' => true,
|
||||
'width' => '10px',
|
||||
], $attributes);
|
||||
$this->collection->push(new Column($attributes));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a action column.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @return $this
|
||||
*/
|
||||
public function addAction(array $attributes = [])
|
||||
{
|
||||
$attributes = array_merge([
|
||||
'defaultContent' => '',
|
||||
'data' => 'action',
|
||||
'name' => 'action',
|
||||
'title' => 'Action',
|
||||
'render' => null,
|
||||
'orderable' => false,
|
||||
'searchable' => false,
|
||||
'exportable' => false,
|
||||
'printable' => true,
|
||||
'footer' => '',
|
||||
], $attributes);
|
||||
$this->collection->push(new Column($attributes));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a index column.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @return $this
|
||||
*/
|
||||
public function addIndex(array $attributes = [])
|
||||
{
|
||||
$indexColumn = Config::get('datatables.index_column', 'DT_Row_Index');
|
||||
$attributes = array_merge([
|
||||
'defaultContent' => '',
|
||||
'data' => $indexColumn,
|
||||
'name' => $indexColumn,
|
||||
'title' => '',
|
||||
'render' => null,
|
||||
'orderable' => false,
|
||||
'searchable' => false,
|
||||
'exportable' => false,
|
||||
'printable' => true,
|
||||
'footer' => '',
|
||||
], $attributes);
|
||||
$this->collection->push(new Column($attributes));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup ajax parameter
|
||||
*
|
||||
* @param string|array $attributes
|
||||
* @return $this
|
||||
*/
|
||||
public function ajax($attributes)
|
||||
{
|
||||
$this->ajax = $attributes;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate DataTable's table html.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @param bool $drawFooter
|
||||
* @return string
|
||||
*/
|
||||
public function table(array $attributes = [], $drawFooter = false)
|
||||
{
|
||||
$this->tableAttributes = array_merge($this->tableAttributes, $attributes);
|
||||
|
||||
$th = $this->compileTableHeaders();
|
||||
$htmlAttr = $this->html->attributes($this->tableAttributes);
|
||||
|
||||
$tableHtml = '<table ' . $htmlAttr . '>';
|
||||
$tableHtml .= '<thead><tr>' . implode('', $th) . '</tr></thead>';
|
||||
if ($drawFooter) {
|
||||
$tf = $this->compileTableFooter();
|
||||
$tableHtml .= '<tfoot><tr>' . implode('', $tf) . '</tr></tfoot>';
|
||||
}
|
||||
$tableHtml .= '</table>';
|
||||
|
||||
return $tableHtml;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile table headers and to support responsive extension.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function compileTableHeaders()
|
||||
{
|
||||
$th = [];
|
||||
foreach ($this->collection->toArray() as $row) {
|
||||
$thAttr = $this->html->attributes(
|
||||
array_only($row, ['class', 'id', 'width', 'style', 'data-class', 'data-hide'])
|
||||
);
|
||||
$th[] = '<th ' . $thAttr . '>' . $row['title'] . '</th>';
|
||||
}
|
||||
|
||||
return $th;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile table footer contents.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function compileTableFooter()
|
||||
{
|
||||
$footer = [];
|
||||
foreach ($this->collection->toArray() as $row) {
|
||||
$footer[] = '<th>' . $row['footer'] . '</th>';
|
||||
}
|
||||
|
||||
return $footer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure DataTable's parameters.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @return $this
|
||||
*/
|
||||
public function parameters(array $attributes = [])
|
||||
{
|
||||
$this->attributes = array_merge($this->attributes, $attributes);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set custom javascript template.
|
||||
*
|
||||
* @param string $template
|
||||
* @return $this
|
||||
*/
|
||||
public function setTemplate($template)
|
||||
{
|
||||
$this->template = $template;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get collection of columns.
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getColumns()
|
||||
{
|
||||
return $this->collection;
|
||||
}
|
||||
}
|
@@ -1,74 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\Datatables\Html;
|
||||
|
||||
use Illuminate\Support\Fluent;
|
||||
|
||||
/**
|
||||
* Class Column.
|
||||
*
|
||||
* @package Yajra\Datatables\Html
|
||||
* @see https://datatables.net/reference/option/ for possible columns option
|
||||
* @author Arjay Angeles <aqangeles@gmail.com>
|
||||
*/
|
||||
class Column extends Fluent
|
||||
{
|
||||
/**
|
||||
* @param array $attributes
|
||||
*/
|
||||
public function __construct($attributes = [])
|
||||
{
|
||||
$attributes['orderable'] = isset($attributes['orderable']) ? $attributes['orderable'] : true;
|
||||
$attributes['searchable'] = isset($attributes['searchable']) ? $attributes['searchable'] : true;
|
||||
$attributes['exportable'] = isset($attributes['exportable']) ? $attributes['exportable'] : true;
|
||||
$attributes['printable'] = isset($attributes['printable']) ? $attributes['printable'] : true;
|
||||
$attributes['footer'] = isset($attributes['footer']) ? $attributes['footer'] : '';
|
||||
|
||||
// Allow methods override attribute value
|
||||
foreach ($attributes as $attribute => $value) {
|
||||
$method = 'parse' . ucfirst(strtolower($attribute));
|
||||
if (method_exists($this, $method)) {
|
||||
$attributes[$attribute] = $this->$method($value);
|
||||
}
|
||||
}
|
||||
|
||||
parent::__construct($attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse render attribute.
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return string|null
|
||||
*/
|
||||
public function parseRender($value)
|
||||
{
|
||||
/** @var \Illuminate\Contracts\View\Factory $view */
|
||||
$view = app('view');
|
||||
$parameters = [];
|
||||
|
||||
if (is_array($value)) {
|
||||
$parameters = array_except($value, 0);
|
||||
$value = $value[0];
|
||||
}
|
||||
|
||||
if (is_callable($value)) {
|
||||
return $value($parameters);
|
||||
} elseif ($view->exists($value)) {
|
||||
return $view->make($value)->with($parameters)->render();
|
||||
}
|
||||
|
||||
return $value ? $this->parseRenderAsString($value) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display render value as is.
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return string
|
||||
*/
|
||||
private function parseRenderAsString($value)
|
||||
{
|
||||
return "function(data,type,full,meta){return $value;}";
|
||||
}
|
||||
}
|
@@ -1,25 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\Datatables\Html;
|
||||
|
||||
use Illuminate\Support\Fluent;
|
||||
|
||||
/**
|
||||
* Class Parameters.
|
||||
*
|
||||
* @package Yajra\Datatables\Html
|
||||
* @see https://datatables.net/reference/option/ for possible columns option
|
||||
* @author Arjay Angeles <aqangeles@gmail.com>
|
||||
*/
|
||||
class Parameters extends Fluent
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $attributes = [
|
||||
'serverSide' => true,
|
||||
'processing' => true,
|
||||
'ajax' => '',
|
||||
'columns' => []
|
||||
];
|
||||
}
|
@@ -1,17 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\Datatables\Processors;
|
||||
namespace Yajra\DataTables\Processors;
|
||||
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\Config;
|
||||
use Yajra\Datatables\Helper;
|
||||
use Yajra\DataTables\Utilities\Helper;
|
||||
|
||||
/**
|
||||
* Class DataProcessor.
|
||||
*
|
||||
* @package Yajra\Datatables
|
||||
* @author Arjay Angeles <aqangeles@gmail.com>
|
||||
*/
|
||||
class DataProcessor
|
||||
{
|
||||
/**
|
||||
@@ -27,7 +20,7 @@ class DataProcessor
|
||||
protected $escapeColumns = [];
|
||||
|
||||
/**
|
||||
* Processed data output
|
||||
* Processed data output.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
@@ -63,11 +56,21 @@ class DataProcessor
|
||||
*/
|
||||
protected $includeIndex;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $rawColumns;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $exceptions = ['DT_RowId', 'DT_RowClass', 'DT_RowData', 'DT_RowAttr'];
|
||||
|
||||
/**
|
||||
* @param mixed $results
|
||||
* @param array $columnDef
|
||||
* @param array $templates
|
||||
* @param int $start
|
||||
* @param int $start
|
||||
*/
|
||||
public function __construct($results, array $columnDef, array $templates, $start)
|
||||
{
|
||||
@@ -75,14 +78,18 @@ class DataProcessor
|
||||
$this->appendColumns = $columnDef['append'];
|
||||
$this->editColumns = $columnDef['edit'];
|
||||
$this->excessColumns = $columnDef['excess'];
|
||||
$this->onlyColumns = $columnDef['only'];
|
||||
$this->escapeColumns = $columnDef['escape'];
|
||||
$this->includeIndex = $columnDef['index'];
|
||||
$this->rawColumns = $columnDef['raw'];
|
||||
$this->makeHidden = $columnDef['hidden'];
|
||||
$this->makeVisible = $columnDef['visible'];
|
||||
$this->templates = $templates;
|
||||
$this->start = $start;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process data to output on browser
|
||||
* Process data to output on browser.
|
||||
*
|
||||
* @param bool $object
|
||||
* @return array
|
||||
@@ -90,13 +97,14 @@ class DataProcessor
|
||||
public function process($object = false)
|
||||
{
|
||||
$this->output = [];
|
||||
$indexColumn = Config::get('datatables.index_column', 'DT_Row_Index');
|
||||
$indexColumn = config('datatables.index_column', 'DT_RowIndex');
|
||||
|
||||
foreach ($this->results as $row) {
|
||||
$data = Helper::convertToArray($row);
|
||||
$data = Helper::convertToArray($row, ['hidden' => $this->makeHidden, 'visible' => $this->makeVisible]);
|
||||
$value = $this->addColumns($data, $row);
|
||||
$value = $this->editColumns($value, $row);
|
||||
$value = $this->setupRowVariables($value, $row);
|
||||
$value = $this->selectOnlyNeededColumns($value);
|
||||
$value = $this->removeExcessColumns($value);
|
||||
|
||||
if ($this->includeIndex) {
|
||||
@@ -162,6 +170,31 @@ class DataProcessor
|
||||
->getData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get only needed columns.
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
protected function selectOnlyNeededColumns(array $data)
|
||||
{
|
||||
if (is_null($this->onlyColumns)) {
|
||||
return $data;
|
||||
} else {
|
||||
$results = [];
|
||||
foreach ($this->onlyColumns as $onlyColumn) {
|
||||
Arr::set($results, $onlyColumn, Arr::get($data, $onlyColumn));
|
||||
}
|
||||
foreach ($this->exceptions as $exception) {
|
||||
if ($column = Arr::get($data, $exception)) {
|
||||
Arr::set($results, $exception, $column);
|
||||
}
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove declared hidden columns.
|
||||
*
|
||||
@@ -171,7 +204,7 @@ class DataProcessor
|
||||
protected function removeExcessColumns(array $data)
|
||||
{
|
||||
foreach ($this->excessColumns as $value) {
|
||||
unset($data[$value]);
|
||||
Arr::forget($data, $value);
|
||||
}
|
||||
|
||||
return $data;
|
||||
@@ -185,11 +218,9 @@ class DataProcessor
|
||||
*/
|
||||
public function flatten(array $array)
|
||||
{
|
||||
$return = [];
|
||||
$exceptions = ['DT_RowId', 'DT_RowClass', 'DT_RowData', 'DT_RowAttr'];
|
||||
|
||||
$return = [];
|
||||
foreach ($array as $key => $value) {
|
||||
if (in_array($key, $exceptions)) {
|
||||
if (in_array($key, $this->exceptions)) {
|
||||
$return[$key] = $value;
|
||||
} else {
|
||||
$return[] = $value;
|
||||
@@ -209,12 +240,11 @@ class DataProcessor
|
||||
{
|
||||
return array_map(function ($row) {
|
||||
if ($this->escapeColumns == '*') {
|
||||
$row = $this->escapeRow($row, $this->escapeColumns);
|
||||
} else {
|
||||
foreach ($this->escapeColumns as $key) {
|
||||
if (array_get($row, $key)) {
|
||||
array_set($row, $key, e(array_get($row, $key)));
|
||||
}
|
||||
$row = $this->escapeRow($row);
|
||||
} elseif (is_array($this->escapeColumns)) {
|
||||
$columns = array_diff($this->escapeColumns, $this->rawColumns);
|
||||
foreach ($columns as $key) {
|
||||
Arr::set($row, $key, e(Arr::get($row, $key)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,19 +256,21 @@ class DataProcessor
|
||||
* Escape all values of row.
|
||||
*
|
||||
* @param array $row
|
||||
* @param string|array $escapeColumns
|
||||
* @return array
|
||||
*/
|
||||
protected function escapeRow(array $row, $escapeColumns)
|
||||
protected function escapeRow(array $row)
|
||||
{
|
||||
foreach ($row as $key => $value) {
|
||||
if (is_array($value)) {
|
||||
$row[$key] = $this->escapeRow($value, $escapeColumns);
|
||||
} else {
|
||||
$row[$key] = e($value);
|
||||
$arrayDot = array_filter(Arr::dot($row));
|
||||
foreach ($arrayDot as $key => $value) {
|
||||
if (! in_array($key, $this->rawColumns)) {
|
||||
$arrayDot[$key] = e($value);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($arrayDot as $key => $value) {
|
||||
Arr::set($row, $key, $value);
|
||||
}
|
||||
|
||||
return $row;
|
||||
}
|
||||
}
|
||||
|
@@ -1,16 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\Datatables\Processors;
|
||||
namespace Yajra\DataTables\Processors;
|
||||
|
||||
use Illuminate\Support\Arr;
|
||||
use Yajra\Datatables\Helper;
|
||||
use Yajra\DataTables\Utilities\Helper;
|
||||
|
||||
/**
|
||||
* Class RowProcessor.
|
||||
*
|
||||
* @package Yajra\Datatables
|
||||
* @author Arjay Angeles <aqangeles@gmail.com>
|
||||
*/
|
||||
class RowProcessor
|
||||
{
|
||||
/**
|
||||
@@ -36,7 +30,7 @@ class RowProcessor
|
||||
/**
|
||||
* Process DT RowId and Class value.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param string $attribute
|
||||
* @param string|callable $template
|
||||
* @return $this
|
||||
*/
|
||||
@@ -57,7 +51,7 @@ class RowProcessor
|
||||
* Process DT Row Data and Attr.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param array $template
|
||||
* @param array $template
|
||||
* @return $this
|
||||
*/
|
||||
public function rowData($attribute, array $template)
|
||||
|
771
vendor/yajra/laravel-datatables-oracle/src/QueryDataTable.php
vendored
Normal file
771
vendor/yajra/laravel-datatables-oracle/src/QueryDataTable.php
vendored
Normal file
@@ -0,0 +1,771 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\DataTables;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Database\Query\Builder;
|
||||
use Yajra\DataTables\Utilities\Helper;
|
||||
use Illuminate\Database\Query\Expression;
|
||||
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
||||
|
||||
class QueryDataTable extends DataTableAbstract
|
||||
{
|
||||
/**
|
||||
* Builder object.
|
||||
*
|
||||
* @var \Illuminate\Database\Query\Builder
|
||||
*/
|
||||
protected $query;
|
||||
|
||||
/**
|
||||
* Database connection used.
|
||||
*
|
||||
* @var \Illuminate\Database\Connection
|
||||
*/
|
||||
protected $connection;
|
||||
|
||||
/**
|
||||
* Flag for ordering NULLS LAST option.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $nullsLast = false;
|
||||
|
||||
/**
|
||||
* Flag to check if query preparation was already done.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $prepared = false;
|
||||
|
||||
/**
|
||||
* Query callback for custom pagination using limit without offset.
|
||||
*
|
||||
* @var callable
|
||||
*/
|
||||
protected $limitCallback;
|
||||
|
||||
/**
|
||||
* Flag to skip total records count query.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $skipTotalRecords = false;
|
||||
|
||||
/**
|
||||
* Flag to keep the select bindings.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $keepSelectBindings = false;
|
||||
|
||||
/**
|
||||
* Can the DataTable engine be created with these parameters.
|
||||
*
|
||||
* @param mixed $source
|
||||
* @return bool
|
||||
*/
|
||||
public static function canCreate($source)
|
||||
{
|
||||
return $source instanceof Builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Illuminate\Database\Query\Builder $builder
|
||||
*/
|
||||
public function __construct(Builder $builder)
|
||||
{
|
||||
$this->query = $builder;
|
||||
$this->request = app('datatables.request');
|
||||
$this->config = app('datatables.config');
|
||||
$this->columns = $builder->columns;
|
||||
$this->connection = $builder->getConnection();
|
||||
if ($this->config->isDebugging()) {
|
||||
$this->connection->enableQueryLog();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Organizes works.
|
||||
*
|
||||
* @param bool $mDataSupport
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function make($mDataSupport = true)
|
||||
{
|
||||
try {
|
||||
$this->prepareQuery();
|
||||
|
||||
$results = $this->results();
|
||||
$processed = $this->processResults($results, $mDataSupport);
|
||||
$data = $this->transform($results, $processed);
|
||||
|
||||
return $this->render($data);
|
||||
} catch (\Exception $exception) {
|
||||
return $this->errorResponse($exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare query by executing count, filter, order and paginate.
|
||||
*/
|
||||
protected function prepareQuery()
|
||||
{
|
||||
if (! $this->prepared) {
|
||||
$this->totalRecords = $this->totalCount();
|
||||
|
||||
if ($this->totalRecords) {
|
||||
$this->filterRecords();
|
||||
$this->ordering();
|
||||
$this->paginate();
|
||||
}
|
||||
}
|
||||
|
||||
$this->prepared = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Skip total records and set the recordsTotal equals to recordsFiltered.
|
||||
* This will improve the performance by skipping the total count query.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function skipTotalRecords()
|
||||
{
|
||||
$this->skipTotalRecords = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Keep the select bindings.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function keepSelectBindings()
|
||||
{
|
||||
$this->keepSelectBindings = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Count total items.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function totalCount()
|
||||
{
|
||||
if ($this->skipTotalRecords) {
|
||||
$this->isFilterApplied = true;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return $this->totalRecords ? $this->totalRecords : $this->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* Count filtered items.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
protected function filteredCount()
|
||||
{
|
||||
$this->filteredRecords = $this->filteredRecords ?: $this->count();
|
||||
if ($this->skipTotalRecords) {
|
||||
$this->totalRecords = $this->filteredRecords;
|
||||
}
|
||||
|
||||
return $this->filteredRecords;
|
||||
}
|
||||
|
||||
/**
|
||||
* Counts current query.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
$builder = $this->prepareCountQuery();
|
||||
$table = $this->connection->raw('(' . $builder->toSql() . ') count_row_table');
|
||||
|
||||
return $this->connection->table($table)
|
||||
->setBindings($builder->getBindings())
|
||||
->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare count query builder.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Query\Builder
|
||||
*/
|
||||
protected function prepareCountQuery()
|
||||
{
|
||||
$builder = clone $this->query;
|
||||
|
||||
if (! $this->isComplexQuery($builder)) {
|
||||
$row_count = $this->wrap('row_count');
|
||||
$builder->select($this->connection->raw("'1' as {$row_count}"));
|
||||
if (! $this->keepSelectBindings) {
|
||||
$builder->setBindings([], 'select');
|
||||
}
|
||||
}
|
||||
|
||||
return $builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if builder query uses complex sql.
|
||||
*
|
||||
* @param \Illuminate\Database\Query\Builder $builder
|
||||
* @return bool
|
||||
*/
|
||||
protected function isComplexQuery($builder)
|
||||
{
|
||||
return Str::contains(Str::lower($builder->toSql()), ['union', 'having', 'distinct', 'order by', 'group by']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap column with DB grammar.
|
||||
*
|
||||
* @param string $column
|
||||
* @return string
|
||||
*/
|
||||
protected function wrap($column)
|
||||
{
|
||||
return $this->connection->getQueryGrammar()->wrap($column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get paginated results.
|
||||
*
|
||||
* @return \Illuminate\Support\Collection
|
||||
*/
|
||||
public function results()
|
||||
{
|
||||
return $this->query->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get filtered, ordered and paginated query.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Query\Builder
|
||||
*/
|
||||
public function getFilteredQuery()
|
||||
{
|
||||
$this->prepareQuery();
|
||||
|
||||
return $this->getQuery();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get query builder instance.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Query\Builder
|
||||
*/
|
||||
public function getQuery()
|
||||
{
|
||||
return $this->query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform column search.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function columnSearch()
|
||||
{
|
||||
$columns = $this->request->columns();
|
||||
|
||||
foreach ($columns as $index => $column) {
|
||||
$column = $this->getColumnName($index);
|
||||
|
||||
if (! $this->request->isColumnSearchable($index) || $this->isBlacklisted($column) && ! $this->hasFilterColumn($column)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($this->hasFilterColumn($column)) {
|
||||
$keyword = $this->getColumnSearchKeyword($index, $raw = true);
|
||||
$this->applyFilterColumn($this->getBaseQueryBuilder(), $column, $keyword);
|
||||
} else {
|
||||
$column = $this->resolveRelationColumn($column);
|
||||
$keyword = $this->getColumnSearchKeyword($index);
|
||||
$this->compileColumnSearch($index, $column, $keyword);
|
||||
}
|
||||
|
||||
$this->isFilterApplied = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if column has custom filter handler.
|
||||
*
|
||||
* @param string $columnName
|
||||
* @return bool
|
||||
*/
|
||||
public function hasFilterColumn($columnName)
|
||||
{
|
||||
return isset($this->columnDef['filter'][$columnName]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get column keyword to use for search.
|
||||
*
|
||||
* @param int $i
|
||||
* @param bool $raw
|
||||
* @return string
|
||||
*/
|
||||
protected function getColumnSearchKeyword($i, $raw = false)
|
||||
{
|
||||
$keyword = $this->request->columnKeyword($i);
|
||||
if ($raw || $this->request->isRegex($i)) {
|
||||
return $keyword;
|
||||
}
|
||||
|
||||
return $this->setupKeyword($keyword);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply filterColumn api search.
|
||||
*
|
||||
* @param mixed $query
|
||||
* @param string $columnName
|
||||
* @param string $keyword
|
||||
* @param string $boolean
|
||||
*/
|
||||
protected function applyFilterColumn($query, $columnName, $keyword, $boolean = 'and')
|
||||
{
|
||||
$query = $this->getBaseQueryBuilder($query);
|
||||
$callback = $this->columnDef['filter'][$columnName]['method'];
|
||||
|
||||
if ($this->query instanceof EloquentBuilder) {
|
||||
$builder = $this->query->newModelInstance()->newQuery();
|
||||
} else {
|
||||
$builder = $this->query->newQuery();
|
||||
}
|
||||
|
||||
$callback($builder, $keyword);
|
||||
|
||||
$query->addNestedWhereQuery($this->getBaseQueryBuilder($builder), $boolean);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the base query builder instance.
|
||||
*
|
||||
* @param mixed $instance
|
||||
* @return \Illuminate\Database\Query\Builder
|
||||
*/
|
||||
protected function getBaseQueryBuilder($instance = null)
|
||||
{
|
||||
if (! $instance) {
|
||||
$instance = $this->query;
|
||||
}
|
||||
|
||||
if ($instance instanceof EloquentBuilder) {
|
||||
return $instance->getQuery();
|
||||
}
|
||||
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the proper column name be used.
|
||||
*
|
||||
* @param string $column
|
||||
* @return string
|
||||
*/
|
||||
protected function resolveRelationColumn($column)
|
||||
{
|
||||
return $column;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile queries for column search.
|
||||
*
|
||||
* @param int $i
|
||||
* @param string $column
|
||||
* @param string $keyword
|
||||
*/
|
||||
protected function compileColumnSearch($i, $column, $keyword)
|
||||
{
|
||||
if ($this->request->isRegex($i)) {
|
||||
$column = strstr($column, '(') ? $this->connection->raw($column) : $column;
|
||||
$this->regexColumnSearch($column, $keyword);
|
||||
} else {
|
||||
$this->compileQuerySearch($this->query, $column, $keyword, '');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile regex query column search.
|
||||
*
|
||||
* @param mixed $column
|
||||
* @param string $keyword
|
||||
*/
|
||||
protected function regexColumnSearch($column, $keyword)
|
||||
{
|
||||
switch ($this->connection->getDriverName()) {
|
||||
case 'oracle':
|
||||
$sql = ! $this->config->isCaseInsensitive()
|
||||
? 'REGEXP_LIKE( ' . $column . ' , ? )'
|
||||
: 'REGEXP_LIKE( LOWER(' . $column . ') , ?, \'i\' )';
|
||||
break;
|
||||
|
||||
case 'pgsql':
|
||||
$column = $this->castColumn($column);
|
||||
$sql = ! $this->config->isCaseInsensitive() ? $column . ' ~ ?' : $column . ' ~* ? ';
|
||||
break;
|
||||
|
||||
default:
|
||||
$sql = ! $this->config->isCaseInsensitive()
|
||||
? $column . ' REGEXP ?'
|
||||
: 'LOWER(' . $column . ') REGEXP ?';
|
||||
$keyword = Str::lower($keyword);
|
||||
}
|
||||
|
||||
$this->query->whereRaw($sql, [$keyword]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap a column and cast based on database driver.
|
||||
*
|
||||
* @param string $column
|
||||
* @return string
|
||||
*/
|
||||
protected function castColumn($column)
|
||||
{
|
||||
switch ($this->connection->getDriverName()) {
|
||||
case 'pgsql':
|
||||
return 'CAST(' . $column . ' as TEXT)';
|
||||
case 'firebird':
|
||||
return 'CAST(' . $column . ' as VARCHAR(255))';
|
||||
default:
|
||||
return $column;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile query builder where clause depending on configurations.
|
||||
*
|
||||
* @param mixed $query
|
||||
* @param string $column
|
||||
* @param string $keyword
|
||||
* @param string $boolean
|
||||
*/
|
||||
protected function compileQuerySearch($query, $column, $keyword, $boolean = 'or')
|
||||
{
|
||||
$column = $this->addTablePrefix($query, $column);
|
||||
$column = $this->castColumn($column);
|
||||
$sql = $column . ' LIKE ?';
|
||||
|
||||
if ($this->config->isCaseInsensitive()) {
|
||||
$sql = 'LOWER(' . $column . ') LIKE ?';
|
||||
}
|
||||
|
||||
$query->{$boolean . 'WhereRaw'}($sql, [$this->prepareKeyword($keyword)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Patch for fix about ambiguous field.
|
||||
* Ambiguous field error will appear when query use join table and search with keyword.
|
||||
*
|
||||
* @param mixed $query
|
||||
* @param string $column
|
||||
* @return string
|
||||
*/
|
||||
protected function addTablePrefix($query, $column)
|
||||
{
|
||||
if (strpos($column, '.') === false) {
|
||||
$q = $this->getBaseQueryBuilder($query);
|
||||
if (! $q->from instanceof Expression) {
|
||||
$column = $q->from . '.' . $column;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->wrap($column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare search keyword based on configurations.
|
||||
*
|
||||
* @param string $keyword
|
||||
* @return string
|
||||
*/
|
||||
protected function prepareKeyword($keyword)
|
||||
{
|
||||
if ($this->config->isStartsWithSearch()) {
|
||||
return "$keyword%";
|
||||
}
|
||||
|
||||
if ($this->config->isCaseInsensitive()) {
|
||||
$keyword = Str::lower($keyword);
|
||||
}
|
||||
|
||||
if ($this->config->isWildcard()) {
|
||||
$keyword = Helper::wildcardLikeString($keyword);
|
||||
}
|
||||
|
||||
if ($this->config->isSmartSearch()) {
|
||||
$keyword = "%$keyword%";
|
||||
}
|
||||
|
||||
return $keyword;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add custom filter handler for the give column.
|
||||
*
|
||||
* @param string $column
|
||||
* @param callable $callback
|
||||
* @return $this
|
||||
*/
|
||||
public function filterColumn($column, callable $callback)
|
||||
{
|
||||
$this->columnDef['filter'][$column] = ['method' => $callback];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Order each given columns versus the given custom sql.
|
||||
*
|
||||
* @param array $columns
|
||||
* @param string $sql
|
||||
* @param array $bindings
|
||||
* @return $this
|
||||
*/
|
||||
public function orderColumns(array $columns, $sql, $bindings = [])
|
||||
{
|
||||
foreach ($columns as $column) {
|
||||
$this->orderColumn($column, str_replace(':column', $column, $sql), $bindings);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override default column ordering.
|
||||
*
|
||||
* @param string $column
|
||||
* @param string $sql
|
||||
* @param array $bindings
|
||||
* @return $this
|
||||
* @internal string $1 Special variable that returns the requested order direction of the column.
|
||||
*/
|
||||
public function orderColumn($column, $sql, $bindings = [])
|
||||
{
|
||||
$this->columnDef['order'][$column] = compact('sql', 'bindings');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set datatables to do ordering with NULLS LAST option.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function orderByNullsLast()
|
||||
{
|
||||
$this->nullsLast = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Paginate dataTable using limit without offset
|
||||
* with additional where clause via callback.
|
||||
*
|
||||
* @param callable $callback
|
||||
* @return $this
|
||||
*/
|
||||
public function limit(callable $callback)
|
||||
{
|
||||
$this->limitCallback = $callback;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform pagination.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function paging()
|
||||
{
|
||||
$limit = (int) $this->request->input('length') > 0 ? $this->request->input('length') : 10;
|
||||
if (is_callable($this->limitCallback)) {
|
||||
$this->query->limit($limit);
|
||||
call_user_func_array($this->limitCallback, [$this->query]);
|
||||
} else {
|
||||
$this->query->skip($this->request->input('start'))->take($limit);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add column in collection.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string|callable $content
|
||||
* @param bool|int $order
|
||||
* @return $this
|
||||
*/
|
||||
public function addColumn($name, $content, $order = false)
|
||||
{
|
||||
$this->pushToBlacklist($name);
|
||||
|
||||
return parent::addColumn($name, $content, $order);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve callback parameter instance.
|
||||
*
|
||||
* @return \Illuminate\Database\Query\Builder
|
||||
*/
|
||||
protected function resolveCallbackParameter()
|
||||
{
|
||||
return $this->query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform default query orderBy clause.
|
||||
*/
|
||||
protected function defaultOrdering()
|
||||
{
|
||||
collect($this->request->orderableColumns())
|
||||
->map(function ($orderable) {
|
||||
$orderable['name'] = $this->getColumnName($orderable['column'], true);
|
||||
|
||||
return $orderable;
|
||||
})
|
||||
->reject(function ($orderable) {
|
||||
return $this->isBlacklisted($orderable['name']) && ! $this->hasOrderColumn($orderable['name']);
|
||||
})
|
||||
->each(function ($orderable) {
|
||||
$column = $this->resolveRelationColumn($orderable['name']);
|
||||
|
||||
if ($this->hasOrderColumn($column)) {
|
||||
$this->applyOrderColumn($column, $orderable);
|
||||
} else {
|
||||
$nullsLastSql = $this->getNullsLastSql($column, $orderable['direction']);
|
||||
$normalSql = $this->wrap($column) . ' ' . $orderable['direction'];
|
||||
$sql = $this->nullsLast ? $nullsLastSql : $normalSql;
|
||||
$this->query->orderByRaw($sql);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if column has custom sort handler.
|
||||
*
|
||||
* @param string $column
|
||||
* @return bool
|
||||
*/
|
||||
protected function hasOrderColumn($column)
|
||||
{
|
||||
return isset($this->columnDef['order'][$column]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply orderColumn custom query.
|
||||
*
|
||||
* @param string $column
|
||||
* @param array $orderable
|
||||
*/
|
||||
protected function applyOrderColumn($column, $orderable)
|
||||
{
|
||||
$sql = $this->columnDef['order'][$column]['sql'];
|
||||
if (is_callable($sql)) {
|
||||
call_user_func($sql, $this->query, $orderable['direction']);
|
||||
} else {
|
||||
$sql = str_replace('$1', $orderable['direction'], $sql);
|
||||
$bindings = $this->columnDef['order'][$column]['bindings'];
|
||||
$this->query->orderByRaw($sql, $bindings);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get NULLS LAST SQL.
|
||||
*
|
||||
* @param string $column
|
||||
* @param string $direction
|
||||
* @return string
|
||||
*/
|
||||
protected function getNullsLastSql($column, $direction)
|
||||
{
|
||||
$sql = $this->config->get('datatables.nulls_last_sql', '%s %s NULLS LAST');
|
||||
|
||||
return str_replace(
|
||||
[':column', ':direction'],
|
||||
[$column, $direction],
|
||||
sprintf($sql, $column, $direction)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform global search for the given keyword.
|
||||
*
|
||||
* @param string $keyword
|
||||
*/
|
||||
protected function globalSearch($keyword)
|
||||
{
|
||||
$this->query->where(function ($query) use ($keyword) {
|
||||
collect($this->request->searchableColumnIndex())
|
||||
->map(function ($index) {
|
||||
return $this->getColumnName($index);
|
||||
})
|
||||
->reject(function ($column) {
|
||||
return $this->isBlacklisted($column) && ! $this->hasFilterColumn($column);
|
||||
})
|
||||
->each(function ($column) use ($keyword, $query) {
|
||||
if ($this->hasFilterColumn($column)) {
|
||||
$this->applyFilterColumn($query, $column, $keyword, 'or');
|
||||
} else {
|
||||
$this->compileQuerySearch($query, $column, $keyword);
|
||||
}
|
||||
|
||||
$this->isFilterApplied = true;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Append debug parameters on output.
|
||||
*
|
||||
* @param array $output
|
||||
* @return array
|
||||
*/
|
||||
protected function showDebugger(array $output)
|
||||
{
|
||||
$query_log = $this->connection->getQueryLog();
|
||||
array_walk_recursive($query_log, function (&$item, $key) {
|
||||
$item = utf8_encode($item);
|
||||
});
|
||||
|
||||
$output['queries'] = $query_log;
|
||||
$output['input'] = $this->request->all();
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attach custom with meta on response.
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
protected function attachAppends(array $data)
|
||||
{
|
||||
$appends = [];
|
||||
foreach ($this->appends as $key => $value) {
|
||||
if (is_callable($value)) {
|
||||
$appends[$key] = value($value($this->getFilteredQuery()));
|
||||
} else {
|
||||
$appends[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return array_merge($data, $appends);
|
||||
}
|
||||
}
|
@@ -1,173 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\Datatables;
|
||||
|
||||
use Exception;
|
||||
use Illuminate\Http\Request as IlluminateRequest;
|
||||
|
||||
/**
|
||||
* Class Request.
|
||||
*
|
||||
* @property array columns
|
||||
* @package Yajra\Datatables
|
||||
* @author Arjay Angeles <aqangeles@gmail.com>
|
||||
*/
|
||||
class Request extends IlluminateRequest
|
||||
{
|
||||
/**
|
||||
* Check if request uses legacy code
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function checkLegacyCode()
|
||||
{
|
||||
if (! $this->get('draw') && $this->get('sEcho')) {
|
||||
throw new Exception('DataTables legacy code is not supported! Please use DataTables 1.10++ coding convention.');
|
||||
} elseif (! $this->get('draw') && ! $this->get('columns')) {
|
||||
throw new Exception('Insufficient parameters');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if Datatables is searchable.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isSearchable()
|
||||
{
|
||||
return $this->get('search')['value'] != '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get column's search value.
|
||||
*
|
||||
* @param integer $index
|
||||
* @return string
|
||||
*/
|
||||
public function columnKeyword($index)
|
||||
{
|
||||
return $this->columns[$index]['search']['value'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if Datatables must uses regular expressions
|
||||
*
|
||||
* @param integer $index
|
||||
* @return string
|
||||
*/
|
||||
public function isRegex($index)
|
||||
{
|
||||
return $this->columns[$index]['search']['regex'] === 'true';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get orderable columns
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function orderableColumns()
|
||||
{
|
||||
if (! $this->isOrderable()) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$orderable = [];
|
||||
for ($i = 0, $c = count($this->get('order')); $i < $c; $i++) {
|
||||
$order_col = (int) $this->get('order')[$i]['column'];
|
||||
$order_dir = $this->get('order')[$i]['dir'];
|
||||
if ($this->isColumnOrderable($order_col)) {
|
||||
$orderable[] = ['column' => $order_col, 'direction' => $order_dir];
|
||||
}
|
||||
}
|
||||
|
||||
return $orderable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if Datatables ordering is enabled.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isOrderable()
|
||||
{
|
||||
return $this->get('order') && count($this->get('order')) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a column is orderable.
|
||||
*
|
||||
* @param integer $index
|
||||
* @return bool
|
||||
*/
|
||||
public function isColumnOrderable($index)
|
||||
{
|
||||
return $this->get('columns')[$index]['orderable'] == 'true';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get searchable column indexes
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function searchableColumnIndex()
|
||||
{
|
||||
$searchable = [];
|
||||
for ($i = 0, $c = count($this->get('columns')); $i < $c; $i++) {
|
||||
if ($this->isColumnSearchable($i, false)) {
|
||||
$searchable[] = $i;
|
||||
}
|
||||
}
|
||||
|
||||
return $searchable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a column is searchable.
|
||||
*
|
||||
* @param integer $i
|
||||
* @param bool $column_search
|
||||
* @return bool
|
||||
*/
|
||||
public function isColumnSearchable($i, $column_search = true)
|
||||
{
|
||||
$columns = $this->get('columns');
|
||||
if ($column_search) {
|
||||
return $columns[$i]['searchable'] == 'true' && $columns[$i]['search']['value'] != '';
|
||||
}
|
||||
|
||||
return $columns[$i]['searchable'] == 'true';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get global search keyword
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function keyword()
|
||||
{
|
||||
return $this->get('search')['value'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get column identity from input or database.
|
||||
*
|
||||
* @param integer $i
|
||||
* @return string
|
||||
*/
|
||||
public function columnName($i)
|
||||
{
|
||||
$column = $this->get('columns')[$i];
|
||||
|
||||
return isset($column['name']) && $column['name'] <> '' ? $column['name'] : $column['data'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if Datatables allow pagination.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isPaginationable()
|
||||
{
|
||||
return ! is_null($this->get('start')) && ! is_null($this->get('length')) && $this->get('length') != -1;
|
||||
}
|
||||
}
|
@@ -1,385 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\Datatables\Services;
|
||||
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
use Illuminate\Support\Facades\Config;
|
||||
use Maatwebsite\Excel\Classes\LaravelExcelWorksheet;
|
||||
use Maatwebsite\Excel\Writers\LaravelExcelWriter;
|
||||
use Yajra\Datatables\Contracts\DataTableButtonsContract;
|
||||
use Yajra\Datatables\Contracts\DataTableContract;
|
||||
use Yajra\Datatables\Contracts\DataTableScopeContract;
|
||||
use Yajra\Datatables\Datatables;
|
||||
use Yajra\Datatables\Transformers\DataTransformer;
|
||||
|
||||
/**
|
||||
* Class DataTable.
|
||||
*
|
||||
* @package Yajra\Datatables\Services
|
||||
* @author Arjay Angeles <aqangeles@gmail.com>
|
||||
*/
|
||||
abstract class DataTable implements DataTableContract, DataTableButtonsContract
|
||||
{
|
||||
/**
|
||||
* @var \Yajra\Datatables\Datatables
|
||||
*/
|
||||
protected $datatables;
|
||||
|
||||
/**
|
||||
* @var \Illuminate\Contracts\View\Factory
|
||||
*/
|
||||
protected $viewFactory;
|
||||
|
||||
/**
|
||||
* Datatables print preview view.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $printPreview = 'datatables::print';
|
||||
|
||||
/**
|
||||
* List of columns to be exported.
|
||||
*
|
||||
* @var string|array
|
||||
*/
|
||||
protected $exportColumns = '*';
|
||||
|
||||
/**
|
||||
* List of columns to be printed.
|
||||
*
|
||||
* @var string|array
|
||||
*/
|
||||
protected $printColumns = '*';
|
||||
|
||||
/**
|
||||
* Query scopes.
|
||||
*
|
||||
* @var \Yajra\Datatables\Contracts\DataTableScopeContract[]
|
||||
*/
|
||||
protected $scopes = [];
|
||||
|
||||
/**
|
||||
* Export filename.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $filename = '';
|
||||
|
||||
/**
|
||||
* DataTable constructor.
|
||||
*
|
||||
* @param \Yajra\Datatables\Datatables $datatables
|
||||
* @param \Illuminate\Contracts\View\Factory $viewFactory
|
||||
*/
|
||||
public function __construct(Datatables $datatables, Factory $viewFactory)
|
||||
{
|
||||
$this->datatables = $datatables;
|
||||
$this->viewFactory = $viewFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process dataTables needed render output.
|
||||
*
|
||||
* @param string $view
|
||||
* @param array $data
|
||||
* @param array $mergeData
|
||||
* @return \Illuminate\Http\JsonResponse|\Illuminate\View\View
|
||||
*/
|
||||
public function render($view, $data = [], $mergeData = [])
|
||||
{
|
||||
if ($this->request()->ajax() && $this->request()->wantsJson()) {
|
||||
return $this->ajax();
|
||||
}
|
||||
|
||||
if ($action = $this->request()->get('action') AND in_array($action, ['print', 'csv', 'excel', 'pdf'])) {
|
||||
if ($action == 'print') {
|
||||
return $this->printPreview();
|
||||
}
|
||||
|
||||
return call_user_func_array([$this, $action], []);
|
||||
}
|
||||
|
||||
return $this->viewFactory->make($view, $data, $mergeData)->with('dataTable', $this->html());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Datatables Request instance.
|
||||
*
|
||||
* @return \Yajra\Datatables\Request
|
||||
*/
|
||||
public function request()
|
||||
{
|
||||
return $this->datatables->getRequest();
|
||||
}
|
||||
|
||||
/**
|
||||
* Display printable view of datatables.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function printPreview()
|
||||
{
|
||||
$data = $this->getDataForPrint();
|
||||
|
||||
return $this->viewFactory->make($this->printPreview, compact('data'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get mapped columns versus final decorated output.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getDataForPrint()
|
||||
{
|
||||
$columns = $this->printColumns();
|
||||
|
||||
return $this->mapResponseToColumns($columns, 'printable');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get printable columns.
|
||||
*
|
||||
* @return array|string
|
||||
*/
|
||||
protected function printColumns()
|
||||
{
|
||||
return is_array($this->printColumns) ? $this->printColumns : $this->getColumnsFromBuilder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get columns definition from html builder.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getColumnsFromBuilder()
|
||||
{
|
||||
return $this->html()->getColumns();
|
||||
}
|
||||
|
||||
/**
|
||||
* Optional method if you want to use html builder.
|
||||
*
|
||||
* @return \Yajra\Datatables\Html\Builder
|
||||
*/
|
||||
public function html()
|
||||
{
|
||||
return $this->builder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Datatables Html Builder instance.
|
||||
*
|
||||
* @return \Yajra\Datatables\Html\Builder
|
||||
*/
|
||||
public function builder()
|
||||
{
|
||||
return $this->datatables->getHtmlBuilder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Map ajax response to columns definition.
|
||||
*
|
||||
* @param mixed $columns
|
||||
* @param string $type
|
||||
* @return array
|
||||
*/
|
||||
protected function mapResponseToColumns($columns, $type)
|
||||
{
|
||||
return array_map(function ($row) use ($columns, $type) {
|
||||
if ($columns) {
|
||||
return (new DataTransformer())->transform($row, $columns, $type);
|
||||
}
|
||||
|
||||
return $row;
|
||||
}, $this->getAjaxResponseData());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get decorated data as defined in datatables ajax response.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getAjaxResponseData()
|
||||
{
|
||||
$this->datatables->getRequest()->merge(['length' => -1]);
|
||||
|
||||
$response = $this->ajax();
|
||||
$data = $response->getData(true);
|
||||
|
||||
return $data['data'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Export results to Excel file.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function excel()
|
||||
{
|
||||
$this->buildExcelFile()->download('xls');
|
||||
}
|
||||
|
||||
/**
|
||||
* Build excel file and prepare for export.
|
||||
*
|
||||
* @return \Maatwebsite\Excel\Writers\LaravelExcelWriter
|
||||
*/
|
||||
protected function buildExcelFile()
|
||||
{
|
||||
/** @var \Maatwebsite\Excel\Excel $excel */
|
||||
$excel = app('excel');
|
||||
|
||||
return $excel->create($this->getFilename(), function (LaravelExcelWriter $excel) {
|
||||
$excel->sheet('exported-data', function (LaravelExcelWorksheet $sheet) {
|
||||
$sheet->fromArray($this->getDataForExport());
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get export filename.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFilename()
|
||||
{
|
||||
return $this->filename ?: $this->filename();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set export filename.
|
||||
*
|
||||
* @param string $filename
|
||||
* @return DataTable
|
||||
*/
|
||||
public function setFilename($filename)
|
||||
{
|
||||
$this->filename = $filename;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get filename for export.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function filename()
|
||||
{
|
||||
return 'export_' . time();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get mapped columns versus final decorated output.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getDataForExport()
|
||||
{
|
||||
$columns = $this->exportColumns();
|
||||
|
||||
return $this->mapResponseToColumns($columns, 'exportable');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get export columns definition.
|
||||
*
|
||||
* @return array|string
|
||||
*/
|
||||
private function exportColumns()
|
||||
{
|
||||
return is_array($this->exportColumns) ? $this->exportColumns : $this->getColumnsFromBuilder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Export results to CSV file.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function csv()
|
||||
{
|
||||
$this->buildExcelFile()->download('csv');
|
||||
}
|
||||
|
||||
/**
|
||||
* Export results to PDF file.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function pdf()
|
||||
{
|
||||
if ('snappy' == Config::get('datatables.pdf_generator', 'excel')) {
|
||||
return $this->snappyPdf();
|
||||
} else {
|
||||
$this->buildExcelFile()->download('pdf');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* PDF version of the table using print preview blade template.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function snappyPdf()
|
||||
{
|
||||
$data = $this->getDataForPrint();
|
||||
$snappy = app('snappy.pdf.wrapper');
|
||||
$snappy->setOptions([
|
||||
'no-outline' => true,
|
||||
'margin-left' => '0',
|
||||
'margin-right' => '0',
|
||||
'margin-top' => '10mm',
|
||||
'margin-bottom' => '10mm',
|
||||
])->setOrientation('landscape');
|
||||
|
||||
return $snappy->loadView($this->printPreview, compact('data'))
|
||||
->download($this->getFilename() . ".pdf");
|
||||
}
|
||||
|
||||
/**
|
||||
* Add basic array query scopes.
|
||||
*
|
||||
* @param \Yajra\Datatables\Contracts\DataTableScopeContract $scope
|
||||
* @return $this
|
||||
*/
|
||||
public function addScope(DataTableScopeContract $scope)
|
||||
{
|
||||
$this->scopes[] = $scope;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply query scopes.
|
||||
*
|
||||
* @param \Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder $query
|
||||
* @return mixed
|
||||
*/
|
||||
protected function applyScopes($query)
|
||||
{
|
||||
foreach ($this->scopes as $scope) {
|
||||
$scope->apply($query);
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default builder parameters.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getBuilderParameters()
|
||||
{
|
||||
return [
|
||||
'order' => [[0, 'desc']],
|
||||
'buttons' => [
|
||||
'create',
|
||||
'export',
|
||||
'print',
|
||||
'reset',
|
||||
'reload',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
@@ -1,75 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\Datatables\Transformers;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Class DataTransformer.
|
||||
*
|
||||
* @package Yajra\Datatables\Transformers
|
||||
* @author Arjay Angeles <aqangeles@gmail.com>
|
||||
*/
|
||||
class DataTransformer
|
||||
{
|
||||
/**
|
||||
* Transform row data by columns definition.
|
||||
*
|
||||
* @param array $row
|
||||
* @param mixed $columns
|
||||
* @param string $type
|
||||
* @return array
|
||||
*/
|
||||
public function transform(array $row, $columns, $type = 'printable')
|
||||
{
|
||||
if ($columns instanceof Collection) {
|
||||
return $this->buildColumnByCollection($row, $columns, $type);
|
||||
}
|
||||
|
||||
return array_only($row, $columns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform row column by collection.
|
||||
*
|
||||
* @param array $row
|
||||
* @param \Illuminate\Support\Collection $columns
|
||||
* @param string $type
|
||||
* @return array
|
||||
*/
|
||||
protected function buildColumnByCollection(array $row, Collection $columns, $type = 'printable')
|
||||
{
|
||||
$results = [];
|
||||
foreach ($columns->all() as $column) {
|
||||
if ($column[$type]) {
|
||||
$title = $column['title'];
|
||||
$data = array_get($row, $column['data']);
|
||||
if ($type == 'exportable') {
|
||||
$data = $this->decodeContent($data);
|
||||
$title = $this->decodeContent($title);
|
||||
}
|
||||
|
||||
$results[$title] = $data;
|
||||
}
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode content to a readable text value.
|
||||
*
|
||||
* @param string $data
|
||||
* @return string
|
||||
*/
|
||||
protected function decodeContent($data)
|
||||
{
|
||||
try {
|
||||
$decoded = html_entity_decode(strip_tags($data), ENT_QUOTES, 'UTF-8');
|
||||
|
||||
return str_replace("\xc2\xa0", ' ', $decoded);
|
||||
} catch (\Exception $e) {
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
}
|
107
vendor/yajra/laravel-datatables-oracle/src/Utilities/Config.php
vendored
Normal file
107
vendor/yajra/laravel-datatables-oracle/src/Utilities/Config.php
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\DataTables\Utilities;
|
||||
|
||||
use Illuminate\Contracts\Config\Repository;
|
||||
|
||||
class Config
|
||||
{
|
||||
/**
|
||||
* @var \Illuminate\Contracts\Config\Repository
|
||||
*/
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* Config constructor.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Config\Repository $repository
|
||||
*/
|
||||
public function __construct(Repository $repository)
|
||||
{
|
||||
$this->repository = $repository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if config uses wild card search.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isWildcard()
|
||||
{
|
||||
return $this->repository->get('datatables.search.use_wildcards', false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if config uses smart search.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isSmartSearch()
|
||||
{
|
||||
return $this->repository->get('datatables.search.smart', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if config uses case insensitive search.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isCaseInsensitive()
|
||||
{
|
||||
return $this->repository->get('datatables.search.case_insensitive', false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if app is in debug mode.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isDebugging()
|
||||
{
|
||||
return $this->repository->get('app.debug', false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the specified configuration value.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function get($key, $default = null)
|
||||
{
|
||||
return $this->repository->get($key, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a given configuration value.
|
||||
*
|
||||
* @param array|string $key
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
*/
|
||||
public function set($key, $value = null)
|
||||
{
|
||||
$this->repository->set($key, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if dataTable config uses multi-term searching.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isMultiTerm()
|
||||
{
|
||||
return $this->repository->get('datatables.search.multi_term', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if dataTable config uses starts_with searching.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isStartsWithSearch()
|
||||
{
|
||||
return $this->repository->get('datatables.search.starts_with', false);
|
||||
}
|
||||
}
|
@@ -1,19 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\Datatables;
|
||||
namespace Yajra\DataTables\Utilities;
|
||||
|
||||
use DateTime;
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
use Illuminate\Filesystem\Filesystem;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\View\Compilers\BladeCompiler;
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
|
||||
/**
|
||||
* Class Helper.
|
||||
*
|
||||
* @package Yajra\Datatables
|
||||
* @author Arjay Angeles <aqangeles@gmail.com>
|
||||
*/
|
||||
class Helper
|
||||
{
|
||||
/**
|
||||
@@ -27,20 +20,20 @@ class Helper
|
||||
{
|
||||
if (self::isItemOrderInvalid($item, $array)) {
|
||||
return array_merge($array, [$item['name'] => $item['content']]);
|
||||
} else {
|
||||
$count = 0;
|
||||
$last = $array;
|
||||
$first = [];
|
||||
foreach ($array as $key => $value) {
|
||||
if ($count == $item['order']) {
|
||||
return array_merge($first, [$item['name'] => $item['content']], $last);
|
||||
}
|
||||
}
|
||||
|
||||
unset($last[$key]);
|
||||
$first[$key] = $value;
|
||||
|
||||
$count++;
|
||||
$count = 0;
|
||||
$last = $array;
|
||||
$first = [];
|
||||
foreach ($array as $key => $value) {
|
||||
if ($count == $item['order']) {
|
||||
return array_merge($first, [$item['name'] => $item['content']], $last);
|
||||
}
|
||||
|
||||
unset($last[$key]);
|
||||
$first[$key] = $value;
|
||||
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,10 +52,10 @@ class Helper
|
||||
/**
|
||||
* Determines if content is callable or blade string, processes and returns.
|
||||
*
|
||||
* @param string|callable $content Pre-processed content
|
||||
* @param array $data data to use with blade template
|
||||
* @param mixed $param parameter to call with callable
|
||||
* @return string Processed content
|
||||
* @param mixed $content Pre-processed content
|
||||
* @param array $data data to use with blade template
|
||||
* @param mixed $param parameter to call with callable
|
||||
* @return mixed
|
||||
*/
|
||||
public static function compileContent($content, array $data, $param)
|
||||
{
|
||||
@@ -79,8 +72,8 @@ class Helper
|
||||
* Parses and compiles strings by using Blade Template System.
|
||||
*
|
||||
* @param string $str
|
||||
* @param array $data
|
||||
* @return string
|
||||
* @param array $data
|
||||
* @return mixed
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function compileBlade($str, $data = [])
|
||||
@@ -89,19 +82,8 @@ class Helper
|
||||
return view($str, $data)->render();
|
||||
}
|
||||
|
||||
$empty_filesystem_instance = new Filesystem();
|
||||
$blade = new BladeCompiler($empty_filesystem_instance, 'datatables');
|
||||
$parsed_string = $blade->compileString($str);
|
||||
|
||||
ob_start() && extract($data, EXTR_SKIP);
|
||||
|
||||
try {
|
||||
eval('?>' . $parsed_string);
|
||||
} catch (\Exception $e) {
|
||||
ob_end_clean();
|
||||
throw $e;
|
||||
}
|
||||
|
||||
eval('?>' . app('blade.compiler')->compileString($str));
|
||||
$str = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
@@ -117,11 +99,13 @@ class Helper
|
||||
*/
|
||||
public static function getMixedValue(array $data, $param)
|
||||
{
|
||||
$param = self::castToArray($param);
|
||||
$casted = self::castToArray($param);
|
||||
|
||||
$data['model'] = $param;
|
||||
|
||||
foreach ($data as $key => $value) {
|
||||
if (isset($param[$key])) {
|
||||
$data[$key] = $param[$key];
|
||||
if (isset($casted[$key])) {
|
||||
$data[$key] = $casted[$key];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,68 +148,25 @@ class Helper
|
||||
return $method;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap value depending on database type.
|
||||
*
|
||||
* @param string $database
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
public static function wrapDatabaseValue($database, $value)
|
||||
{
|
||||
$parts = explode('.', $value);
|
||||
$column = '';
|
||||
foreach ($parts as $key) {
|
||||
$column = static::wrapDatabaseColumn($database, $key, $column);
|
||||
}
|
||||
|
||||
return substr($column, 0, strlen($column) - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Database column wrapper.
|
||||
*
|
||||
* @param string $database
|
||||
* @param string $key
|
||||
* @param string $column
|
||||
* @return string
|
||||
*/
|
||||
public static function wrapDatabaseColumn($database, $key, $column)
|
||||
{
|
||||
switch ($database) {
|
||||
case 'mysql':
|
||||
$column .= '`' . str_replace('`', '``', $key) . '`' . '.';
|
||||
break;
|
||||
|
||||
case 'sqlsrv':
|
||||
$column .= '[' . str_replace(']', ']]', $key) . ']' . '.';
|
||||
break;
|
||||
|
||||
case 'pgsql':
|
||||
case 'sqlite':
|
||||
$column .= '"' . str_replace('"', '""', $key) . '"' . '.';
|
||||
break;
|
||||
|
||||
default:
|
||||
$column .= $key . '.';
|
||||
}
|
||||
|
||||
return $column;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts array object values to associative array.
|
||||
*
|
||||
* @param mixed $row
|
||||
* @param array $filters
|
||||
* @return array
|
||||
*/
|
||||
public static function convertToArray($row)
|
||||
public static function convertToArray($row, $filters = [])
|
||||
{
|
||||
$row = method_exists($row, 'makeHidden') ? $row->makeHidden(Arr::get($filters, 'hidden', [])) : $row;
|
||||
$row = method_exists($row, 'makeVisible') ? $row->makeVisible(Arr::get($filters, 'visible', [])) : $row;
|
||||
$data = $row instanceof Arrayable ? $row->toArray() : (array) $row;
|
||||
foreach (array_keys($data) as $key) {
|
||||
if (is_object($data[$key]) || is_array($data[$key])) {
|
||||
$data[$key] = self::convertToArray($data[$key]);
|
||||
|
||||
foreach ($data as &$value) {
|
||||
if (is_object($value) || is_array($value)) {
|
||||
$value = self::convertToArray($value);
|
||||
}
|
||||
|
||||
unset($value);
|
||||
}
|
||||
|
||||
return $data;
|
||||
@@ -290,9 +231,9 @@ class Helper
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace all pattern occurrences with keyword
|
||||
* Replace all pattern occurrences with keyword.
|
||||
*
|
||||
* @param array $subject
|
||||
* @param array $subject
|
||||
* @param string $keyword
|
||||
* @param string $pattern
|
||||
* @return array
|
||||
@@ -310,4 +251,68 @@ class Helper
|
||||
|
||||
return $parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get column name from string.
|
||||
*
|
||||
* @param string $str
|
||||
* @param bool $wantsAlias
|
||||
* @return string
|
||||
*/
|
||||
public static function extractColumnName($str, $wantsAlias)
|
||||
{
|
||||
$matches = explode(' as ', Str::lower($str));
|
||||
|
||||
if (! empty($matches)) {
|
||||
if ($wantsAlias) {
|
||||
return array_pop($matches);
|
||||
}
|
||||
|
||||
return array_shift($matches);
|
||||
} elseif (strpos($str, '.')) {
|
||||
$array = explode('.', $str);
|
||||
|
||||
return array_pop($array);
|
||||
}
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds % wildcards to the given string.
|
||||
*
|
||||
* @param string $str
|
||||
* @param bool $lowercase
|
||||
* @return string
|
||||
*/
|
||||
public static function wildcardLikeString($str, $lowercase = true)
|
||||
{
|
||||
return static::wildcardString($str, '%', $lowercase);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds wildcards to the given string.
|
||||
*
|
||||
* @param string $str
|
||||
* @param string $wildcard
|
||||
* @param bool $lowercase
|
||||
* @return string
|
||||
*/
|
||||
public static function wildcardString($str, $wildcard, $lowercase = true)
|
||||
{
|
||||
$wild = $wildcard;
|
||||
$chars = preg_split('//u', $str, -1, PREG_SPLIT_NO_EMPTY);
|
||||
|
||||
if (count($chars) > 0) {
|
||||
foreach ($chars as $char) {
|
||||
$wild .= $char . $wildcard;
|
||||
}
|
||||
}
|
||||
|
||||
if ($lowercase) {
|
||||
$wild = Str::lower($wild);
|
||||
}
|
||||
|
||||
return $wild;
|
||||
}
|
||||
}
|
236
vendor/yajra/laravel-datatables-oracle/src/Utilities/Request.php
vendored
Normal file
236
vendor/yajra/laravel-datatables-oracle/src/Utilities/Request.php
vendored
Normal file
@@ -0,0 +1,236 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\DataTables\Utilities;
|
||||
|
||||
/**
|
||||
* @method mixed input($key, $default = null)
|
||||
* @method mixed get($key, $default = null)
|
||||
* @method mixed query($key, $default = null)
|
||||
* @method mixed has($key)
|
||||
* @method mixed merge(array $values)
|
||||
* @method bool wantsJson()
|
||||
* @method bool ajax()
|
||||
* @method array all()
|
||||
*/
|
||||
class Request
|
||||
{
|
||||
/**
|
||||
* @var \Illuminate\Http\Request
|
||||
*/
|
||||
protected $request;
|
||||
|
||||
/**
|
||||
* Request constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->request = app('request');
|
||||
}
|
||||
|
||||
/**
|
||||
* Proxy non existing method calls to request class.
|
||||
*
|
||||
* @param mixed $name
|
||||
* @param mixed $arguments
|
||||
* @return mixed
|
||||
*/
|
||||
public function __call($name, $arguments)
|
||||
{
|
||||
if (method_exists($this->request, $name)) {
|
||||
return call_user_func_array([$this->request, $name], $arguments);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get attributes from request instance.
|
||||
*
|
||||
* @param string $name
|
||||
* @return mixed
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
return $this->request->__get($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all columns request input.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function columns()
|
||||
{
|
||||
return (array) $this->request->input('columns');
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if DataTables is searchable.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isSearchable()
|
||||
{
|
||||
return $this->request->input('search.value') != '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if DataTables must uses regular expressions.
|
||||
*
|
||||
* @param int $index
|
||||
* @return bool
|
||||
*/
|
||||
public function isRegex($index)
|
||||
{
|
||||
return $this->request->input("columns.$index.search.regex") === 'true';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get orderable columns.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function orderableColumns()
|
||||
{
|
||||
if (! $this->isOrderable()) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$orderable = [];
|
||||
for ($i = 0, $c = count($this->request->input('order')); $i < $c; $i++) {
|
||||
$order_col = (int) $this->request->input("order.$i.column");
|
||||
$order_dir = strtolower($this->request->input("order.$i.dir")) === 'asc' ? 'asc' : 'desc';
|
||||
if ($this->isColumnOrderable($order_col)) {
|
||||
$orderable[] = ['column' => $order_col, 'direction' => $order_dir];
|
||||
}
|
||||
}
|
||||
|
||||
return $orderable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if DataTables ordering is enabled.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isOrderable()
|
||||
{
|
||||
return $this->request->input('order') && count($this->request->input('order')) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a column is orderable.
|
||||
*
|
||||
* @param int $index
|
||||
* @return bool
|
||||
*/
|
||||
public function isColumnOrderable($index)
|
||||
{
|
||||
return $this->request->input("columns.$index.orderable", 'true') == 'true';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get searchable column indexes.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function searchableColumnIndex()
|
||||
{
|
||||
$searchable = [];
|
||||
for ($i = 0, $c = count($this->request->input('columns')); $i < $c; $i++) {
|
||||
if ($this->isColumnSearchable($i, false)) {
|
||||
$searchable[] = $i;
|
||||
}
|
||||
}
|
||||
|
||||
return $searchable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a column is searchable.
|
||||
*
|
||||
* @param int $i
|
||||
* @param bool $column_search
|
||||
* @return bool
|
||||
*/
|
||||
public function isColumnSearchable($i, $column_search = true)
|
||||
{
|
||||
if ($column_search) {
|
||||
return
|
||||
(
|
||||
$this->request->input("columns.$i.searchable", 'true') === 'true'
|
||||
||
|
||||
$this->request->input("columns.$i.searchable", 'true') === true
|
||||
)
|
||||
&& $this->columnKeyword($i) != '';
|
||||
}
|
||||
|
||||
return
|
||||
$this->request->input("columns.$i.searchable", 'true') === 'true'
|
||||
||
|
||||
$this->request->input("columns.$i.searchable", 'true') === true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get column's search value.
|
||||
*
|
||||
* @param int $index
|
||||
* @return string
|
||||
*/
|
||||
public function columnKeyword($index)
|
||||
{
|
||||
$keyword = $this->request->input("columns.$index.search.value");
|
||||
|
||||
return $this->prepareKeyword($keyword);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare keyword string value.
|
||||
*
|
||||
* @param string|array $keyword
|
||||
* @return string
|
||||
*/
|
||||
protected function prepareKeyword($keyword)
|
||||
{
|
||||
if (is_array($keyword)) {
|
||||
return implode(' ', $keyword);
|
||||
}
|
||||
|
||||
return $keyword;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get global search keyword.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function keyword()
|
||||
{
|
||||
$keyword = $this->request->input('search.value');
|
||||
|
||||
return $this->prepareKeyword($keyword);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get column identity from input or database.
|
||||
*
|
||||
* @param int $i
|
||||
* @return string
|
||||
*/
|
||||
public function columnName($i)
|
||||
{
|
||||
$column = $this->request->input("columns.$i");
|
||||
|
||||
return isset($column['name']) && $column['name'] != '' ? $column['name'] : $column['data'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if DataTables allow pagination.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isPaginationable()
|
||||
{
|
||||
return ! is_null($this->request->input('start')) &&
|
||||
! is_null($this->request->input('length')) &&
|
||||
$this->request->input('length') != -1;
|
||||
}
|
||||
}
|
@@ -1,86 +0,0 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
/**
|
||||
* DataTables search options.
|
||||
*/
|
||||
'search' => [
|
||||
/**
|
||||
* Smart search will enclose search keyword with wildcard string "%keyword%".
|
||||
* SQL: column LIKE "%keyword%"
|
||||
*/
|
||||
'smart' => true,
|
||||
|
||||
/**
|
||||
* Case insensitive will search the keyword in lower case format.
|
||||
* SQL: LOWER(column) LIKE LOWER(keyword)
|
||||
*/
|
||||
'case_insensitive' => true,
|
||||
|
||||
/**
|
||||
* Wild card will add "%" in between every characters of the keyword.
|
||||
* SQL: column LIKE "%k%e%y%w%o%r%d%"
|
||||
*/
|
||||
'use_wildcards' => false,
|
||||
],
|
||||
|
||||
/**
|
||||
* DataTables fractal configurations.
|
||||
*/
|
||||
'fractal' => [
|
||||
/**
|
||||
* Request key name to parse includes on fractal.
|
||||
*/
|
||||
'includes' => 'include',
|
||||
|
||||
/**
|
||||
* Default fractal serializer.
|
||||
*/
|
||||
'serializer' => 'League\Fractal\Serializer\DataArraySerializer',
|
||||
],
|
||||
|
||||
/**
|
||||
* DataTables script view template.
|
||||
*/
|
||||
'script_template' => 'datatables::script',
|
||||
|
||||
/**
|
||||
* DataTables internal index id response column name.
|
||||
*/
|
||||
'index_column' => 'DT_Row_Index',
|
||||
|
||||
/**
|
||||
* Namespaces used by the generator.
|
||||
*/
|
||||
'namespace' => [
|
||||
/**
|
||||
* Base namespace/directory to create the new file.
|
||||
* This is appended on default Laravel namespace.
|
||||
*
|
||||
* Usage: php artisan datatables:make User
|
||||
* Output: App\DataTables\UserDataTable
|
||||
* With Model: App\User (default model)
|
||||
* Export filename: users_timestamp
|
||||
*/
|
||||
'base' => 'DataTables',
|
||||
|
||||
/**
|
||||
* Base namespace/directory where your model's are located.
|
||||
* This is appended on default Laravel namespace.
|
||||
*
|
||||
* Usage: php artisan datatables:make Post --model
|
||||
* Output: App\DataTables\PostDataTable
|
||||
* With Model: App\Post
|
||||
* Export filename: posts_timestamp
|
||||
*/
|
||||
'model' => '',
|
||||
],
|
||||
|
||||
/**
|
||||
* PDF generator to be used when converting the table to pdf.
|
||||
* Available generators: excel, snappy
|
||||
* Snappy package: barryvdh/laravel-snappy
|
||||
* Excel package: maatwebsite/excel
|
||||
*/
|
||||
'pdf_generator' => 'excel',
|
||||
];
|
122
vendor/yajra/laravel-datatables-oracle/src/config/datatables.php
vendored
Normal file
122
vendor/yajra/laravel-datatables-oracle/src/config/datatables.php
vendored
Normal file
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
/*
|
||||
* DataTables search options.
|
||||
*/
|
||||
'search' => [
|
||||
/*
|
||||
* Smart search will enclose search keyword with wildcard string "%keyword%".
|
||||
* SQL: column LIKE "%keyword%"
|
||||
*/
|
||||
'smart' => true,
|
||||
|
||||
/*
|
||||
* Multi-term search will explode search keyword using spaces resulting into multiple term search.
|
||||
*/
|
||||
'multi_term' => true,
|
||||
|
||||
/*
|
||||
* Case insensitive will search the keyword in lower case format.
|
||||
* SQL: LOWER(column) LIKE LOWER(keyword)
|
||||
*/
|
||||
'case_insensitive' => true,
|
||||
|
||||
/*
|
||||
* Wild card will add "%" in between every characters of the keyword.
|
||||
* SQL: column LIKE "%k%e%y%w%o%r%d%"
|
||||
*/
|
||||
'use_wildcards' => false,
|
||||
|
||||
/*
|
||||
* Perform a search which starts with the given keyword.
|
||||
* SQL: column LIKE "keyword%"
|
||||
*/
|
||||
'starts_with' => false,
|
||||
],
|
||||
|
||||
/*
|
||||
* DataTables internal index id response column name.
|
||||
*/
|
||||
'index_column' => 'DT_RowIndex',
|
||||
|
||||
/*
|
||||
* List of available builders for DataTables.
|
||||
* This is where you can register your custom dataTables builder.
|
||||
*/
|
||||
'engines' => [
|
||||
'eloquent' => Yajra\DataTables\EloquentDataTable::class,
|
||||
'query' => Yajra\DataTables\QueryDataTable::class,
|
||||
'collection' => Yajra\DataTables\CollectionDataTable::class,
|
||||
'resource' => Yajra\DataTables\ApiResourceDataTable::class,
|
||||
],
|
||||
|
||||
/*
|
||||
* DataTables accepted builder to engine mapping.
|
||||
* This is where you can override which engine a builder should use
|
||||
* Note, only change this if you know what you are doing!
|
||||
*/
|
||||
'builders' => [
|
||||
//Illuminate\Database\Eloquent\Relations\Relation::class => 'eloquent',
|
||||
//Illuminate\Database\Eloquent\Builder::class => 'eloquent',
|
||||
//Illuminate\Database\Query\Builder::class => 'query',
|
||||
//Illuminate\Support\Collection::class => 'collection',
|
||||
],
|
||||
|
||||
/*
|
||||
* Nulls last sql pattern for PostgreSQL & Oracle.
|
||||
* For MySQL, use 'CASE WHEN :column IS NULL THEN 1 ELSE 0 END, :column :direction'
|
||||
*/
|
||||
'nulls_last_sql' => ':column :direction NULLS LAST',
|
||||
|
||||
/*
|
||||
* User friendly message to be displayed on user if error occurs.
|
||||
* Possible values:
|
||||
* null - The exception message will be used on error response.
|
||||
* 'throw' - Throws a \Yajra\DataTables\Exceptions\Exception. Use your custom error handler if needed.
|
||||
* 'custom message' - Any friendly message to be displayed to the user. You can also use translation key.
|
||||
*/
|
||||
'error' => env('DATATABLES_ERROR', null),
|
||||
|
||||
/*
|
||||
* Default columns definition of dataTable utility functions.
|
||||
*/
|
||||
'columns' => [
|
||||
/*
|
||||
* List of columns hidden/removed on json response.
|
||||
*/
|
||||
'excess' => ['rn', 'row_num'],
|
||||
|
||||
/*
|
||||
* List of columns to be escaped. If set to *, all columns are escape.
|
||||
* Note: You can set the value to empty array to disable XSS protection.
|
||||
*/
|
||||
'escape' => '*',
|
||||
|
||||
/*
|
||||
* List of columns that are allowed to display html content.
|
||||
* Note: Adding columns to list will make us available to XSS attacks.
|
||||
*/
|
||||
'raw' => ['action'],
|
||||
|
||||
/*
|
||||
* List of columns are are forbidden from being searched/sorted.
|
||||
*/
|
||||
'blacklist' => ['password', 'remember_token'],
|
||||
|
||||
/*
|
||||
* List of columns that are only allowed fo search/sort.
|
||||
* If set to *, all columns are allowed.
|
||||
*/
|
||||
'whitelist' => '*',
|
||||
],
|
||||
|
||||
/*
|
||||
* JsonResponse header and options config.
|
||||
*/
|
||||
'json' => [
|
||||
'header' => [],
|
||||
'options' => 0,
|
||||
],
|
||||
|
||||
];
|
19
vendor/yajra/laravel-datatables-oracle/src/helper.php
vendored
Normal file
19
vendor/yajra/laravel-datatables-oracle/src/helper.php
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
if (! function_exists('datatables')) {
|
||||
/**
|
||||
* Helper to make a new DataTable instance from source.
|
||||
* Or return the factory if source is not set.
|
||||
*
|
||||
* @param mixed $source
|
||||
* @return \Yajra\DataTables\DataTableAbstract|\Yajra\DataTables\DataTables
|
||||
*/
|
||||
function datatables($source = null)
|
||||
{
|
||||
if (is_null($source)) {
|
||||
return app('datatables');
|
||||
}
|
||||
|
||||
return app('datatables')->make($source);
|
||||
}
|
||||
}
|
@@ -15,7 +15,7 @@ if (! function_exists('config_path')) {
|
||||
|
||||
if (! function_exists('public_path')) {
|
||||
/**
|
||||
* Return the path to public dir
|
||||
* Return the path to public dir.
|
||||
*
|
||||
* @param null $path
|
||||
* @return string
|
@@ -1,111 +0,0 @@
|
||||
(function ($, DataTable) {
|
||||
"use strict";
|
||||
|
||||
var _buildUrl = function(dt, action) {
|
||||
var url = dt.ajax.url() || '';
|
||||
var params = dt.ajax.params();
|
||||
params.action = action;
|
||||
|
||||
return url + '?' + $.param(params);
|
||||
};
|
||||
|
||||
DataTable.ext.buttons.excel = {
|
||||
className: 'buttons-excel',
|
||||
|
||||
text: function (dt) {
|
||||
return '<i class="fa fa-file-excel-o"></i> ' + dt.i18n('buttons.excel', 'Excel');
|
||||
},
|
||||
|
||||
action: function (e, dt, button, config) {
|
||||
var url = _buildUrl(dt, 'excel');
|
||||
window.location = url;
|
||||
}
|
||||
};
|
||||
|
||||
DataTable.ext.buttons.export = {
|
||||
extend: 'collection',
|
||||
|
||||
className: 'buttons-export',
|
||||
|
||||
text: function (dt) {
|
||||
return '<i class="fa fa-download"></i> ' + dt.i18n('buttons.export', 'Export') + ' <span class="caret"/>';
|
||||
},
|
||||
|
||||
buttons: ['csv', 'excel', 'pdf']
|
||||
};
|
||||
|
||||
DataTable.ext.buttons.csv = {
|
||||
className: 'buttons-csv',
|
||||
|
||||
text: function (dt) {
|
||||
return '<i class="fa fa-file-excel-o"></i> ' + dt.i18n('buttons.csv', 'CSV');
|
||||
},
|
||||
|
||||
action: function (e, dt, button, config) {
|
||||
var url = _buildUrl(dt, 'csv');
|
||||
window.location = url;
|
||||
}
|
||||
};
|
||||
|
||||
DataTable.ext.buttons.pdf = {
|
||||
className: 'buttons-pdf',
|
||||
|
||||
text: function (dt) {
|
||||
return '<i class="fa fa-file-pdf-o"></i> ' + dt.i18n('buttons.pdf', 'PDF');
|
||||
},
|
||||
|
||||
action: function (e, dt, button, config) {
|
||||
var url = _buildUrl(dt, 'pdf');
|
||||
window.location = url;
|
||||
}
|
||||
};
|
||||
|
||||
DataTable.ext.buttons.print = {
|
||||
className: 'buttons-print',
|
||||
|
||||
text: function (dt) {
|
||||
return '<i class="fa fa-print"></i> ' + dt.i18n('buttons.print', 'Print');
|
||||
},
|
||||
|
||||
action: function (e, dt, button, config) {
|
||||
var url = _buildUrl(dt, 'print');
|
||||
window.location = url;
|
||||
}
|
||||
};
|
||||
|
||||
DataTable.ext.buttons.reset = {
|
||||
className: 'buttons-reset',
|
||||
|
||||
text: function (dt) {
|
||||
return '<i class="fa fa-undo"></i> ' + dt.i18n('buttons.reset', 'Reset');
|
||||
},
|
||||
|
||||
action: function (e, dt, button, config) {
|
||||
dt.search('').draw();
|
||||
}
|
||||
};
|
||||
|
||||
DataTable.ext.buttons.reload = {
|
||||
className: 'buttons-reload',
|
||||
|
||||
text: function (dt) {
|
||||
return '<i class="fa fa-refresh"></i> ' + dt.i18n('buttons.reload', 'Reload');
|
||||
},
|
||||
|
||||
action: function (e, dt, button, config) {
|
||||
dt.draw(false);
|
||||
}
|
||||
};
|
||||
|
||||
DataTable.ext.buttons.create = {
|
||||
className: 'buttons-create',
|
||||
|
||||
text: function (dt) {
|
||||
return '<i class="fa fa-plus"></i> ' + dt.i18n('buttons.create', 'Create');
|
||||
},
|
||||
|
||||
action: function (e, dt, button, config) {
|
||||
window.location = window.location.href.replace(/\/+$/, "") + '/create';
|
||||
}
|
||||
};
|
||||
})(jQuery, jQuery.fn.dataTable);
|
@@ -1,37 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Print Table</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name=description content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<!-- Bootstrap CSS -->
|
||||
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">
|
||||
<style>
|
||||
body {margin: 20px}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<table class="table table-bordered table-condensed table-striped">
|
||||
@foreach($data as $row)
|
||||
@if ($row == reset($data))
|
||||
<tr>
|
||||
@foreach($row as $key => $value)
|
||||
<th>{!! $key !!}</th>
|
||||
@endforeach
|
||||
</tr>
|
||||
@endif
|
||||
<tr>
|
||||
@foreach($row as $key => $value)
|
||||
@if(is_string($value) || is_numeric($value))
|
||||
<td>{!! $value !!}</td>
|
||||
@else
|
||||
<td></td>
|
||||
@endif
|
||||
@endforeach
|
||||
</tr>
|
||||
@endforeach
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
@@ -1 +0,0 @@
|
||||
(function(window,$){window.LaravelDataTables=window.LaravelDataTables||{};window.LaravelDataTables["%1$s"]=$("#%1$s").DataTable(%2$s);})(window,jQuery);
|
Reference in New Issue
Block a user