One Hat Cyber Team
Your IP:
216.73.216.101
Server IP:
198.54.114.155
Server:
Linux server71.web-hosting.com 4.18.0-513.18.1.lve.el8.x86_64 #1 SMP Thu Feb 22 12:55:50 UTC 2024 x86_64
Server Software:
LiteSpeed
PHP Version:
5.6.40
Create File
|
Create Folder
Execute
Dir :
~
/
proc
/
thread-self
/
root
/
proc
/
thread-self
/
cwd
/
Edit File:
yajra.tar
laravel-datatables-oracle/src/CollectionDataTable.php 0000644 00000022626 15111730130 0016674 0 ustar 00 <?php namespace Yajra\DataTables; use Closure; use Exception; use Illuminate\Contracts\Support\Arrayable; use Illuminate\Http\JsonResponse; use Illuminate\Http\Resources\Json\AnonymousResourceCollection; use Illuminate\Support\Arr; use Illuminate\Support\Collection; use Illuminate\Support\Str; class CollectionDataTable extends DataTableAbstract { /** * Collection object. * * @var \Illuminate\Support\Collection<array-key, array> */ public Collection $collection; /** * Collection object. * * @var \Illuminate\Support\Collection<array-key, array> */ public Collection $original; /** * The offset of the first record in the full dataset. * * @var int */ private int $offset = 0; /** * CollectionEngine constructor. * * @param \Illuminate\Support\Collection<array-key, array> $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 array */ protected function serialize($collection): array { return $collection instanceof Arrayable ? $collection->toArray() : (array) $collection; } /** * 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 AnonymousResourceCollection|array|\Illuminate\Support\Collection<array-key, array> $source * @return static */ public static function create($source) { if (is_array($source)) { $source = new Collection($source); } return parent::create($source); } /** * Count results. * * @return int */ public function count(): int { return $this->collection->count(); } /** * Perform column search. * * @return void */ public function columnSearch(): void { for ($i = 0, $c = count($this->request->columns()); $i < $c; $i++) { $column = $this->getColumnName($i); if (is_null($column)) { continue; } if (! $this->request->isColumnSearchable($i) || $this->isBlacklisted($column)) { continue; } $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); /** @var string $value */ $value = Arr::get($data, $column); if ($this->config->isCaseInsensitive()) { if ($regex) { return preg_match('/'.$keyword.'/i', $value) == 1; } return str_contains(Str::lower($value), Str::lower($keyword)); } if ($regex) { return preg_match('/'.$keyword.'/', $value) == 1; } return str_contains($value, $keyword); } ); } } /** * Perform pagination. * * @return void */ public function paging(): void { $offset = $this->request->start() - $this->offset; $length = $this->request->length() > 0 ? $this->request->length() : 10; $this->collection = $this->collection->slice($offset, $length); } /** * Organizes works. * * @param bool $mDataSupport * @return \Illuminate\Http\JsonResponse * * @throws \Exception */ public function make($mDataSupport = true): JsonResponse { 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); } } /** * Get results. * * @return \Illuminate\Support\Collection<array-key, array> */ public function results(): Collection { return $this->collection; } /** * Revert transformed DT_RowIndex back to its original values. * * @param bool $mDataSupport * @return void */ private function revertIndexColumn($mDataSupport): void { if ($this->columnDef['index']) { $indexColumn = config('datatables.index_column', 'DT_RowIndex'); $index = $mDataSupport ? $indexColumn : 0; $start = $this->request->start(); $this->collection->transform(function ($data) use ($index, &$start) { $data[$index] = ++$start; return $data; }); } } /** * 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 static */ public function setOffset(int $offset): self { $this->offset = $offset; return $this; } /** * Perform global search for the given keyword. * * @param string $keyword * @return void */ protected function globalSearch(string $keyword): void { $keyword = $this->config->isCaseInsensitive() ? Str::lower($keyword) : $keyword; $this->collection = $this->collection->filter(function ($row) use ($keyword) { $data = $this->serialize($row); foreach ($this->request->searchableColumnIndex() as $index) { $column = $this->getColumnName($index); $value = Arr::get($data, $column); if (! is_string($value)) { continue; } else { $value = $this->config->isCaseInsensitive() ? Str::lower($value) : $value; } if (Str::contains($value, $keyword)) { return true; } } return false; }); } /** * Perform default query orderBy clause. * * @return void */ protected function defaultOrdering(): void { $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): Closure { return 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 (is_numeric($first[$column] ?? null) && is_numeric($second[$column] ?? null)) { if ($first[$column] < $second[$column]) { $cmp = -1; } elseif ($first[$column] > $second[$column]) { $cmp = 1; } else { $cmp = 0; } } elseif ($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; }; } /** * Resolve callback parameter instance. * * @return array<int|string, mixed> */ protected function resolveCallbackParameter(): array { return [$this, false]; } } laravel-datatables-oracle/src/Utilities/Config.php 0000644 00000005135 15111730130 0016213 0 ustar 00 <?php namespace Yajra\DataTables\Utilities; use Illuminate\Contracts\Config\Repository; class Config { /** * @var \Illuminate\Contracts\Config\Repository */ private Repository $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(): bool { return (bool) $this->repository->get('datatables.search.use_wildcards', false); } /** * Check if config uses smart search. * * @return bool */ public function isSmartSearch(): bool { return (bool) $this->repository->get('datatables.search.smart', true); } /** * Check if config uses case-insensitive search. * * @return bool */ public function isCaseInsensitive(): bool { return (bool) $this->repository->get('datatables.search.case_insensitive', false); } /** * Check if app is in debug mode. * * @return bool */ public function isDebugging(): bool { return (bool) $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(): bool { return (bool) $this->repository->get('datatables.search.multi_term', true); } /** * Check if dataTable config uses starts_with searching. * * @return bool */ public function isStartsWithSearch(): bool { return (bool) $this->repository->get('datatables.search.starts_with', false); } public function jsonOptions(): int { /** @var int $options */ $options = $this->repository->get('datatables.json.options', 0); return $options; } public function jsonHeaders(): array { return (array) $this->repository->get('datatables.json.header', []); } } laravel-datatables-oracle/src/Utilities/Request.php 0000644 00000014642 15111730130 0016441 0 ustar 00 <?php namespace Yajra\DataTables\Utilities; use Illuminate\Http\Request as BaseRequest; /** * @mixin \Illuminate\Http\Request */ class Request { /** * @var BaseRequest */ protected BaseRequest $request; /** * Request constructor. */ public function __construct() { $this->request = app('request'); } /** * Proxy non-existing method calls to base request class. * * @param string $name * @param array $arguments * @return mixed */ public function __call($name, $arguments) { $callback = [$this->request, $name]; if (is_callable($callback)) { return call_user_func_array($callback, $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(): array { return (array) $this->request->input('columns'); } /** * Check if DataTables is searchable. * * @return bool */ public function isSearchable(): bool { return $this->request->input('search.value') != ''; } /** * Check if DataTables must uses regular expressions. * * @param int $index * @return bool */ public function isRegex(int $index): bool { return $this->request->input("columns.$index.search.regex") === 'true'; } /** * Get orderable columns. * * @return array */ public function orderableColumns(): array { if (! $this->isOrderable()) { return []; } $orderable = []; for ($i = 0, $c = count((array) $this->request->input('order')); $i < $c; $i++) { /** @var int $order_col */ $order_col = $this->request->input("order.$i.column"); /** @var string $direction */ $direction = $this->request->input("order.$i.dir"); $order_dir = strtolower($direction) === '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(): bool { return $this->request->input('order') && count((array) $this->request->input('order')) > 0; } /** * Check if a column is orderable. * * @param int $index * @return bool */ public function isColumnOrderable(int $index): bool { return $this->request->input("columns.$index.orderable", 'true') == 'true'; } /** * Get searchable column indexes. * * @return array */ public function searchableColumnIndex() { $searchable = []; $columns = (array) $this->request->input('columns'); for ($i = 0, $c = count($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(int $i, bool $column_search = true): bool { 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(int $index): string { /** @var string $keyword */ $keyword = $this->request->input("columns.$index.search.value") ?? ''; return $this->prepareKeyword($keyword); } /** * Prepare keyword string value. * * @param float|array|int|string $keyword * @return string */ protected function prepareKeyword(float|array|int|string $keyword): string { if (is_array($keyword)) { return implode(' ', $keyword); } return (string) $keyword; } /** * Get global search keyword. * * @return string */ public function keyword(): string { /** @var string $keyword */ $keyword = $this->request->input('search.value') ?? ''; return $this->prepareKeyword($keyword); } /** * Get column name by index. * * @param int $i * @return string|null */ public function columnName(int $i): ?string { /** @var string[] $column */ $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(): bool { return ! is_null($this->request->input('start')) && ! is_null($this->request->input('length')) && $this->request->input('length') != -1; } /** * @return BaseRequest */ public function getBaseRequest(): BaseRequest { return $this->request; } /** * Get starting record value. * * @return int */ public function start(): int { $start = $this->request->input('start', 0); return is_numeric($start) ? intval($start) : 0; } /** * Get per page length. * * @return int */ public function length(): int { $length = $this->request->input('length', 10); return is_numeric($length) ? intval($length) : 10; } /** * Get draw request. * * @return int */ public function draw(): int { $draw = $this->request->input('draw', 0); return is_numeric($draw) ? intval($draw) : 0; } } laravel-datatables-oracle/src/Utilities/Helper.php 0000644 00000026665 15111730130 0016240 0 ustar 00 <?php namespace Yajra\DataTables\Utilities; use Closure; use DateTime; use Illuminate\Contracts\Support\Arrayable; use Illuminate\Support\Arr; use Illuminate\Support\Str; use ReflectionFunction; use ReflectionMethod; class Helper { /** * Places item of extra columns into results by care of their order. * * @param array $item * @param array $array * @return array */ public static function includeInArray($item, $array) { if (self::isItemOrderInvalid($item, $array)) { return array_merge($array, [$item['name'] => $item['content']]); } $count = 0; $last = $array; $first = []; foreach ($array as $key => $value) { if ($count == $item['order']) { continue; } unset($last[$key]); $first[$key] = $value; $count++; } return array_merge($first, [$item['name'] => $item['content']], $last); } /** * Check if item order is valid. * * @param array $item * @param array $array * @return bool */ protected static function isItemOrderInvalid($item, $array) { return $item['order'] === false || $item['order'] >= count($array); } /** * Gets the parameter of a callable thing (from is_callable) and returns it's arguments using reflection. * * @param callable $callable * @return \ReflectionParameter[] * * @throws \ReflectionException * @throws \InvalidArgumentException */ private static function reflectCallableParameters($callable) { /* loosely after https://github.com/technically-php/callable-reflection/blob/main/src/CallableReflection.php#L72-L86. Licence is compatible, both project use MIT */ if ($callable instanceof Closure) { $reflection = new ReflectionFunction($callable); } elseif (is_string($callable) && function_exists($callable)) { $reflection = new ReflectionFunction($callable); } elseif (is_string($callable) && str_contains($callable, '::')) { $reflection = new ReflectionMethod($callable); } elseif (is_object($callable) && method_exists($callable, '__invoke')) { $reflection = new ReflectionMethod($callable, '__invoke'); } else { throw new \InvalidArgumentException('argument is not callable or the code is wrong'); } return $reflection->getParameters(); } /** * Determines if content is callable or blade string, processes and returns. * * @param mixed $content Pre-processed content * @param array $data data to use with blade template * @param array|object $param parameter to call with callable * @return mixed * * @throws \ReflectionException */ public static function compileContent($content, array $data, array|object $param) { if (is_string($content)) { return static::compileBlade($content, static::getMixedValue($data, $param)); } if (is_callable($content)) { $arguments = self::reflectCallableParameters($content); if (count($arguments) > 0) { return app()->call($content, [$arguments[0]->name => $param]); } return $content($param); } if (is_array($content)) { [$view, $viewData] = $content; return static::compileBlade($view, static::getMixedValue($data, $param) + $viewData); } return $content; } /** * Parses and compiles strings by using Blade Template System. * * @param string $str * @param array $data * @return false|string */ public static function compileBlade($str, $data = []) { if (view()->exists($str)) { /** @var view-string $str */ return view($str, $data)->render(); } ob_start() && extract($data, EXTR_SKIP); eval('?>'.app('blade.compiler')->compileString($str)); $str = ob_get_contents(); ob_end_clean(); return $str; } /** * Get a mixed value of custom data and the parameters. * * @param array $data * @param array|object $param * @return array */ public static function getMixedValue(array $data, array|object $param) { $casted = self::castToArray($param); $data['model'] = $param; foreach ($data as $key => $value) { if (isset($casted[$key])) { $data[$key] = $casted[$key]; } } return $data; } /** * Cast the parameter into an array. * * @param array|object $param * @return array */ public static function castToArray(array|object $param): array { if ($param instanceof Arrayable) { return $param->toArray(); } return (array) $param; } /** * Get equivalent or method of query builder. * * @param string $method * @return string */ public static function getOrMethod($method) { if (! Str::contains(Str::lower($method), 'or')) { return 'or'.ucfirst($method); } return $method; } /** * Converts array object values to associative array. * * @param mixed $row * @param array $filters * @return array */ public static function convertToArray($row, $filters = []) { if (Arr::get($filters, 'ignore_getters') && is_object($row) && method_exists($row, 'getAttributes')) { $data = $row->getAttributes(); if (method_exists($row, 'getRelations')) { foreach ($row->getRelations() as $relationName => $relation) { if (is_iterable($relation)) { foreach ($relation as $relationItem) { $data[$relationName][] = self::convertToArray($relationItem, ['ignore_getters' => true]); } } else { $data[$relationName] = self::convertToArray($relation, ['ignore_getters' => true]); } } } return $data; } $row = is_object($row) && method_exists($row, 'makeHidden') ? $row->makeHidden(Arr::get($filters, 'hidden', [])) : $row; $row = is_object($row) && method_exists($row, 'makeVisible') ? $row->makeVisible(Arr::get($filters, 'visible', [])) : $row; $data = $row instanceof Arrayable ? $row->toArray() : (array) $row; foreach ($data as &$value) { if (is_object($value) || is_array($value)) { $value = self::convertToArray($value); } unset($value); } return $data; } /** * @param array $data * @return array */ public static function transform(array $data) { return array_map(function ($row) { return self::transformRow($row); }, $data); } /** * Transform row data into an array. * * @param array $row * @return array */ protected static function transformRow($row) { foreach ($row as $key => $value) { if ($value instanceof DateTime) { $row[$key] = $value->format('Y-m-d H:i:s'); } else { if (is_object($value) && method_exists($value, '__toString')) { $row[$key] = $value->__toString(); } else { $row[$key] = $value; } } } return $row; } /** * Build parameters depending on # of arguments passed. * * @param array $args * @return array */ public static function buildParameters(array $args) { $parameters = []; if (count($args) > 2) { $parameters[] = $args[0]; foreach ($args[1] as $param) { $parameters[] = $param; } } else { foreach ($args[0] as $param) { $parameters[] = $param; } } return $parameters; } /** * Replace all pattern occurrences with keyword. * * @param array $subject * @param string $keyword * @param string $pattern * @return array */ public static function replacePatternWithKeyword(array $subject, $keyword, $pattern = '$1') { $parameters = []; foreach ($subject as $param) { if (is_array($param)) { $parameters[] = self::replacePatternWithKeyword($param, $keyword, $pattern); } else { $parameters[] = str_replace($pattern, $keyword, $param); } } 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 (count($matches) > 1) { 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 = (array) 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; } public static function toJsonScript(array $parameters, int $options = 0): string { $values = []; $replacements = []; foreach (Arr::dot($parameters) as $key => $value) { if (self::isJavascript($value, $key)) { $values[] = trim($value); Arr::set($parameters, $key, '%'.$key.'%'); $replacements[] = '"%'.$key.'%"'; } } $new = []; foreach ($parameters as $key => $value) { Arr::set($new, $key, $value); } $json = (string) json_encode($new, $options); return str_replace($replacements, $values, $json); } public static function isJavascript(string|array|object|null $value, string $key): bool { if (empty($value) || is_array($value) || is_object($value)) { return false; } /** @var array $callbacks */ $callbacks = config('datatables.callback', ['$', '$.', 'function']); if (Str::startsWith($key, 'language.')) { return false; } return Str::startsWith(trim($value), $callbacks) || Str::contains($key, ['editor', 'minDate', 'maxDate']); } } laravel-datatables-oracle/src/Contracts/DataTable.php 0000644 00000002603 15111730130 0016611 0 ustar 00 <?php namespace Yajra\DataTables\Contracts; use Illuminate\Http\JsonResponse; use Illuminate\Support\Collection; interface DataTable { /** * Get results. * * @return \Illuminate\Support\Collection<int, array> */ public function results(): Collection; /** * Count results. * * @return int */ public function count(): int; /** * Count total items. * * @return int */ public function totalCount(): int; /** * Set auto filter off and run your own filter. * Overrides global search. * * @param callable $callback * @param bool $globalSearch * @return static */ public function filter(callable $callback, $globalSearch = false): self; /** * Perform global search. * * @return void */ public function filtering(): void; /** * Perform column search. * * @return void */ public function columnSearch(): void; /** * Perform pagination. * * @return void */ public function paging(): void; /** * Perform sorting of columns. * * @return void */ public function ordering(): void; /** * Organizes works. * * @param bool $mDataSupport * @return \Illuminate\Http\JsonResponse */ public function make($mDataSupport = true): JsonResponse; } laravel-datatables-oracle/src/Contracts/Formatter.php 0000644 00000000371 15111730130 0016733 0 ustar 00 <?php namespace Yajra\DataTables\Contracts; interface Formatter { /** * @param mixed $value * @param array|\Illuminate\Database\Eloquent\Model|object $row * @return string */ public function format($value, $row); } laravel-datatables-oracle/src/Exceptions/Exception.php 0000644 00000000126 15111730130 0017105 0 ustar 00 <?php namespace Yajra\DataTables\Exceptions; class Exception extends \Exception { } laravel-datatables-oracle/src/DataTablesServiceProvider.php 0000644 00000004415 15111730130 0020073 0 ustar 00 <?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) { $canCreate = [$class, 'canCreate']; if (is_callable($canCreate) && ! call_user_func_array($canCreate, func_get_args())) { throw new \InvalidArgumentException(); } $create = [$class, 'create']; if (is_callable($create)) { return call_user_func_array($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'); } } laravel-datatables-oracle/src/EloquentDataTable.php 0000644 00000021510 15111730130 0016364 0 ustar 00 <?php namespace Yajra\DataTables; use Illuminate\Contracts\Database\Eloquent\Builder as EloquentBuilder; use Illuminate\Database\Eloquent\Model; 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\MorphTo; use Illuminate\Database\Eloquent\Relations\Relation; use Yajra\DataTables\Exceptions\Exception; /** * @property EloquentBuilder $query */ class EloquentDataTable extends QueryDataTable { /** * EloquentEngine constructor. * * @param Model|EloquentBuilder $model */ public function __construct(Model|EloquentBuilder $model) { $builder = match (true) { $model instanceof Model => $model->newQuery(), $model instanceof Relation => $model->getQuery(), $model instanceof EloquentBuilder => $model, }; parent::__construct($builder->getQuery()); $this->query = $builder; } /** * Can the DataTable engine be created with these parameters. * * @param mixed $source * @return bool */ public static function canCreate($source): bool { return $source instanceof EloquentBuilder; } /** * 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(): string { return $this->query->getModel()->getKeyName(); } /** * @inheritDoc */ protected function compileQuerySearch($query, string $column, string $keyword, string $boolean = 'or', bool $nested = false): void { if (substr_count($column, '.') > 1) { $parts = explode('.', $column); $firstRelation = array_shift($parts); $column = implode('.', $parts); if ($this->isMorphRelation($firstRelation)) { $query->{$boolean.'WhereHasMorph'}( $firstRelation, '*', function (EloquentBuilder $query) use ($column, $keyword) { parent::compileQuerySearch($query, $column, $keyword, ''); } ); } else { $query->{$boolean.'WhereHas'}($firstRelation, function (EloquentBuilder $query) use ($column, $keyword) { self::compileQuerySearch($query, $column, $keyword, '', true); }); } return; } $parts = explode('.', $column); $newColumn = array_pop($parts); $relation = implode('.', $parts); if (! $nested && $this->isNotEagerLoaded($relation)) { parent::compileQuerySearch($query, $column, $keyword, $boolean); return; } if ($this->isMorphRelation($relation)) { $query->{$boolean.'WhereHasMorph'}( $relation, '*', function (EloquentBuilder $query) use ($newColumn, $keyword) { parent::compileQuerySearch($query, $newColumn, $keyword, ''); } ); } else { $query->{$boolean.'WhereHas'}($relation, function (EloquentBuilder $query) use ($newColumn, $keyword) { parent::compileQuerySearch($query, $newColumn, $keyword, ''); }); } } /** * 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(); } /** * Check if a relation is a morphed one or not. * * @param string $relation * @return bool */ protected function isMorphRelation($relation) { $isMorph = false; if ($relation !== null && $relation !== '') { $relationParts = explode('.', $relation); $firstRelation = array_shift($relationParts); $model = $this->query->getModel(); $isMorph = method_exists($model, $firstRelation) && $model->$firstRelation() instanceof MorphTo; } return $isMorph; } /** * Resolve the proper column name be used. * * @param string $column * @return string * * @throws \Yajra\DataTables\Exceptions\Exception */ protected function resolveRelationColumn(string $column): string { $parts = explode('.', $column); $columnName = array_pop($parts); $relation = implode('.', $parts); if ($this->isNotEagerLoaded($relation)) { return $column; } return $this->joinEagerLoadedColumn($relation, $columnName); } /** * 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 = $model->getRelatedPivotKeyName(); $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->getFirstKeyName(); $pivotFK = $model->getQualifiedLocalKeyName(); $this->performJoin($pivot, $pivotPK, $pivotFK); $related = $model->getRelated(); $table = $related->getTable(); $tablePK = $model->getSecondLocalKeyName(); $foreign = $pivot.'.'.$tablePK; $other = $related->getQualifiedKeyName(); $lastQuery->addSelect($lastQuery->getModel()->getTable().'.*'); 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 * @return void */ protected function performJoin($table, $foreign, $other, $type = 'left'): void { $joins = []; foreach ((array) $this->getBaseQueryBuilder()->joins as $key => $join) { $joins[] = $join->table; } if (! in_array($table, $joins)) { $this->getBaseQueryBuilder()->join($table, $foreign, '=', $other, $type); } } } laravel-datatables-oracle/src/helper.php 0000644 00000001356 15111730130 0014313 0 ustar 00 <?php if (! function_exists('datatables')) { /** * Helper to make a new DataTable instance from source. * Or return the factory if source is not set. * * @param \Illuminate\Contracts\Database\Query\Builder|\Illuminate\Contracts\Database\Eloquent\Builder|\Illuminate\Support\Collection|array|null $source * @return \Yajra\DataTables\DataTables|\Yajra\DataTables\DataTableAbstract * * @throws \Yajra\DataTables\Exceptions\Exception */ function datatables($source = null) { /** @var Yajra\DataTables\DataTables $dataTable */ $dataTable = app('datatables'); if (is_null($source)) { return $dataTable; } return $dataTable->make($source); } } laravel-datatables-oracle/src/Processors/RowProcessor.php 0000644 00000002720 15111730130 0017641 0 ustar 00 <?php namespace Yajra\DataTables\Processors; use Illuminate\Support\Arr; use Yajra\DataTables\Utilities\Helper; class RowProcessor { /** * @param array $data * @param array|object $row */ public function __construct(protected array $data, protected $row) { } /** * Process DT RowId and Class value. * * @param string $attribute * @param string|callable $template * @return $this */ public function rowValue($attribute, $template) { if (! empty($template)) { if (! is_callable($template) && Arr::get($this->data, $template)) { $this->data[$attribute] = Arr::get($this->data, $template); } else { $this->data[$attribute] = Helper::compileContent($template, $this->data, $this->row); } } return $this; } /** * Process DT Row Data and Attr. * * @param string $attribute * @param array $template * @return $this */ public function rowData($attribute, array $template) { if (count($template)) { $this->data[$attribute] = []; foreach ($template as $key => $value) { $this->data[$attribute][$key] = Helper::compileContent($value, $this->data, $this->row); } } return $this; } /** * @return array */ public function getData() { return $this->data; } } laravel-datatables-oracle/src/Processors/DataProcessor.php 0000644 00000017761 15111730130 0017756 0 ustar 00 <?php namespace Yajra\DataTables\Processors; use Illuminate\Contracts\Support\Htmlable; use Illuminate\Support\Arr; use Yajra\DataTables\Contracts\Formatter; use Yajra\DataTables\Utilities\Helper; class DataProcessor { /** * @var int */ protected int $start; /** * @var array */ protected array $output = []; /** * @var array<array-key, array{name: string, content: mixed}> */ protected array $appendColumns = []; /** * @var array<array-key, array{name: string, content: mixed}> */ protected array $editColumns = []; /** * @var array */ protected array $templates = []; /** * @var array */ protected array $rawColumns = []; /** * @var array|string[] */ protected array $exceptions = ['DT_RowId', 'DT_RowClass', 'DT_RowData', 'DT_RowAttr']; /** * @var array */ protected array $onlyColumns = []; /** * @var array */ protected array $makeHidden = []; /** * @var array */ protected array $makeVisible = []; /** * @var array */ protected array $excessColumns = []; /** * @var string|array */ protected mixed $escapeColumns = []; /** * @var iterable */ protected iterable $results; /** * @var bool */ protected bool $includeIndex = false; /** * @var bool */ protected bool $ignoreGetters = false; /** * @param iterable $results * @param array $columnDef * @param array $templates * @param int $start */ public function __construct($results, array $columnDef, array $templates, int $start = 0) { $this->results = $results; $this->appendColumns = $columnDef['append'] ?? []; $this->editColumns = $columnDef['edit'] ?? []; $this->excessColumns = $columnDef['excess'] ?? []; $this->onlyColumns = $columnDef['only'] ?? []; $this->escapeColumns = $columnDef['escape'] ?? []; $this->includeIndex = $columnDef['index'] ?? false; $this->rawColumns = $columnDef['raw'] ?? []; $this->makeHidden = $columnDef['hidden'] ?? []; $this->makeVisible = $columnDef['visible'] ?? []; $this->ignoreGetters = $columnDef['ignore_getters'] ?? false; $this->templates = $templates; $this->start = $start; } /** * Process data to output on browser. * * @param bool $object * @return array */ public function process($object = false): array { $this->output = []; $indexColumn = config('datatables.index_column', 'DT_RowIndex'); foreach ($this->results as $row) { $data = Helper::convertToArray($row, ['hidden' => $this->makeHidden, 'visible' => $this->makeVisible, 'ignore_getters' => $this->ignoreGetters]); $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) { $value[$indexColumn] = ++$this->start; } $this->output[] = $object ? $value : $this->flatten($value); } return $this->escapeColumns($this->output); } /** * Process add columns. * * @param array $data * @param array|object|\Illuminate\Database\Eloquent\Model $row * @return array */ protected function addColumns(array $data, $row): array { foreach ($this->appendColumns as $value) { $content = $value['content']; if ($content instanceof Formatter) { $column = str_replace('_formatted', '', $value['name']); $value['content'] = $content->format($data[$column], $row); if (isset($data[$column])) { $value['content'] = $content->format($data[$column], $row); } } else { $value['content'] = Helper::compileContent($content, $data, $row); } $data = Helper::includeInArray($value, $data); } return $data; } /** * Process edit columns. * * @param array $data * @param array|object $row * @return array */ protected function editColumns(array $data, object|array $row): array { foreach ($this->editColumns as $value) { $value['content'] = Helper::compileContent($value['content'], $data, $row); Arr::set($data, $value['name'], $value['content']); } return $data; } /** * Setup additional DT row variables. * * @param array $data * @param array|object $row * @return array */ protected function setupRowVariables(array $data, object|array $row): array { $processor = new RowProcessor($data, $row); return $processor ->rowValue('DT_RowId', $this->templates['DT_RowId']) ->rowValue('DT_RowClass', $this->templates['DT_RowClass']) ->rowData('DT_RowData', $this->templates['DT_RowData']) ->rowData('DT_RowAttr', $this->templates['DT_RowAttr']) ->getData(); } /** * Get only needed columns. * * @param array $data * @return array */ protected function selectOnlyNeededColumns(array $data): array { if (empty($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. * * @param array $data * @return array */ protected function removeExcessColumns(array $data): array { foreach ($this->excessColumns as $value) { Arr::forget($data, $value); } return $data; } /** * Flatten array with exceptions. * * @param array $array * @return array */ public function flatten(array $array): array { $return = []; foreach ($array as $key => $value) { if (in_array($key, $this->exceptions)) { $return[$key] = $value; } else { $return[] = $value; } } return $return; } /** * Escape column values as declared. * * @param array $output * @return array */ protected function escapeColumns(array $output): array { return array_map(function ($row) { if ($this->escapeColumns == '*') { $row = $this->escapeRow($row); } elseif (is_array($this->escapeColumns)) { $columns = array_diff($this->escapeColumns, $this->rawColumns); foreach ($columns as $key) { /** @var string $content */ $content = Arr::get($row, $key); Arr::set($row, $key, e($content)); } } return $row; }, $output); } /** * Escape all string or Htmlable values of row. * * @param array $row * @return array */ protected function escapeRow(array $row): array { $arrayDot = array_filter(Arr::dot($row)); foreach ($arrayDot as $key => $value) { if (! in_array($key, $this->rawColumns)) { $arrayDot[$key] = (is_string($value) || $value instanceof Htmlable) ? e($value) : $value; } } foreach ($arrayDot as $key => $value) { Arr::set($row, $key, $value); } return $row; } } laravel-datatables-oracle/src/DataTableAbstract.php 0000644 00000061254 15111730130 0016344 0 ustar 00 <?php namespace Yajra\DataTables; use Illuminate\Contracts\Support\Arrayable; use Illuminate\Http\JsonResponse; use Illuminate\Support\Arr; use Illuminate\Support\Str; use Illuminate\Support\Traits\Macroable; use Psr\Log\LoggerInterface; use Yajra\DataTables\Contracts\DataTable; use Yajra\DataTables\Contracts\Formatter; use Yajra\DataTables\Processors\DataProcessor; use Yajra\DataTables\Utilities\Helper; /** * @method static setTransformer($transformer) * @method static setSerializer($transformer) * * @property-read mixed $transformer * @property-read mixed $serializer * * @see https://github.com/yajra/laravel-datatables-fractal for transformer related methods. */ abstract class DataTableAbstract implements DataTable { use Macroable; /** * DataTables Request object. * * @var \Yajra\DataTables\Utilities\Request */ public Utilities\Request $request; /** * @var \Psr\Log\LoggerInterface|null */ protected ?LoggerInterface $logger = null; /** * Array of result columns/fields. * * @var array|null */ protected ?array $columns = []; /** * DT columns definitions container (add/edit/remove/filter/order/escape). * * @var array */ protected array $columnDef = [ 'index' => false, 'ignore_getters' => false, 'append' => [], 'edit' => [], 'filter' => [], 'order' => [], 'only' => null, 'hidden' => [], 'visible' => [], ]; /** * Extra/Added columns. * * @var array */ protected array $extraColumns = []; /** * Total records. * * @var int|null */ protected ?int $totalRecords = null; /** * Total filtered records. * * @var int|null */ protected ?int $filteredRecords = null; /** * Auto-filter flag. * * @var bool */ protected bool $autoFilter = true; /** * Callback to override global search. * * @var callable */ protected $filterCallback = null; /** * DT row templates container. * * @var array */ protected array $templates = [ 'DT_RowId' => '', 'DT_RowClass' => '', 'DT_RowData' => [], 'DT_RowAttr' => [], ]; /** * Custom ordering callback. * * @var callable|null */ protected $orderCallback = null; /** * Skip pagination as needed. * * @var bool */ protected bool $skipPaging = false; /** * Array of data to append on json response. * * @var array */ protected array $appends = []; /** * @var \Yajra\DataTables\Utilities\Config */ protected Utilities\Config $config; /** * @var mixed */ protected mixed $serializer; /** * @var array */ protected array $searchPanes = []; protected mixed $transformer; protected bool $editOnlySelectedColumns = false; /** * 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 static */ public static function create($source) { return new static($source); } /** * @param string|array $columns * @param string|callable|\Yajra\DataTables\Contracts\Formatter $formatter * @return $this */ public function formatColumn($columns, $formatter): static { if (is_string($formatter) && class_exists($formatter)) { $formatter = app($formatter); } if ($formatter instanceof Formatter) { foreach ((array) $columns as $column) { $this->addColumn($column.'_formatted', $formatter); } return $this; } if (is_callable($formatter)) { foreach ((array) $columns as $column) { $this->addColumn( $column.'_formatted', function ($row) use ($column, $formatter) { return $formatter(data_get($row, $column), $row); } ); } return $this; } foreach ((array) $columns as $column) { $this->addColumn( $column.'_formatted', function ($row) use ($column) { return data_get($row, $column); } ); } return $this; } /** * Add column in collection. * * @param string $name * @param string|callable|Formatter $content * @param bool|int $order * @return $this */ public function addColumn($name, $content, $order = false): static { $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(): static { $this->columnDef['index'] = true; return $this; } /** * Prevent the getters Mutators to be applied when converting a collection * of the Models into the final JSON. * * @return $this */ public function ignoreGetters(): static { $this->columnDef['ignore_getters'] = true; return $this; } /** * Edit column's content. * * @param string $name * @param string|callable $content * @return $this */ public function editColumn($name, $content): static { if ($this->editOnlySelectedColumns) { if (! count($this->request->columns()) || in_array($name, Arr::pluck($this->request->columns(), 'name'))) { $this->columnDef['edit'][] = ['name' => $name, 'content' => $content]; } } else { $this->columnDef['edit'][] = ['name' => $name, 'content' => $content]; } return $this; } /** * Remove column from collection. * * @return $this */ public function removeColumn(): static { $names = func_get_args(); $this->columnDef['excess'] = array_merge($this->getColumnsDefinition()['excess'], $names); return $this; } /** * Get columns definition. * * @return array */ protected function getColumnsDefinition(): array { $config = (array) $this->config->get('datatables.columns'); $allowed = ['excess', 'escape', 'raw', 'blacklist', 'whitelist']; return array_replace_recursive(Arr::only($config, $allowed), $this->columnDef); } /** * Get only selected columns in response. * * @param array $columns * @return $this */ public function only(array $columns = []): static { $this->columnDef['only'] = $columns; return $this; } /** * Declare columns to escape values. * * @param string|array $columns * @return $this */ public function escapeColumns($columns = '*'): static { $this->columnDef['escape'] = $columns; return $this; } /** * Add a makeHidden() to the row object. * * @param array $attributes * @return $this */ public function makeHidden(array $attributes = []): static { $hidden = (array) Arr::get($this->columnDef, 'hidden', []); $this->columnDef['hidden'] = array_merge_recursive($hidden, $attributes); return $this; } /** * Add a makeVisible() to the row object. * * @param array $attributes * @return $this */ public function makeVisible(array $attributes = []): static { $visible = (array) Arr::get($this->columnDef, 'visible', []); $this->columnDef['visible'] = array_merge_recursive($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): static { if ($merge) { /** @var array[] $config */ $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): static { $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): static { $this->templates['DT_RowId'] = $content; return $this; } /** * Set DT_RowData templates. * * @param array $data * @return $this */ public function setRowData(array $data): static { $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): static { $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): static { $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): static { $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 = ''): static { if (is_array($key)) { $this->appends = $key; } 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(string $key, callable $value): static { $this->appends[$key] = $value; return $this; } /** * Override default ordering method with a closure callback. * * @param callable $closure * @return $this */ public function order(callable $closure): static { $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): static { $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(array|string $whitelist = '*'): static { $this->columnDef['whitelist'] = $whitelist; return $this; } /** * Set smart search config at runtime. * * @param bool $state * @return $this */ public function smart(bool $state = true): static { $this->config->set('datatables.search.smart', $state); return $this; } /** * Set starts_with search config at runtime. * * @param bool $state * @return $this */ public function startsWithSearch(bool $state = true): static { $this->config->set('datatables.search.starts_with', $state); return $this; } /** * Set multi_term search config at runtime. * * @param bool $multiTerm * @return $this */ public function setMultiTerm(bool $multiTerm = true): static { $this->config->set('datatables.search.multi_term', $multiTerm); return $this; } /** * Set total records manually. * * @param int $total * @return $this */ public function setTotalRecords(int $total): static { $this->totalRecords = $total; return $this; } /** * Skip total records and set the recordsTotal equals to recordsFiltered. * This will improve the performance by skipping the total count query. * * @return $this * * @deprecated Just use setTotalRecords instead. */ public function skipTotalRecords(): static { $this->totalRecords = 0; return $this; } /** * Set filtered records manually. * * @param int $total * @return $this */ public function setFilteredRecords(int $total): static { $this->filteredRecords = $total; return $this; } /** * Skip pagination as needed. * * @return $this */ public function skipPaging(): static { $this->skipPaging = true; return $this; } /** * Skip auto filtering as needed. * * @return $this */ public function skipAutoFilter(): static { $this->autoFilter = false; return $this; } /** * Push a new column name to blacklist. * * @param string $column * @return $this */ public function pushToBlacklist($column): static { if (! $this->isBlacklisted($column)) { $this->columnDef['blacklist'][] = $column; } return $this; } /** * Check if column is blacklisted. * * @param string $column * @return bool */ protected function isBlacklisted($column): bool { $colDef = $this->getColumnsDefinition(); if (in_array($column, $colDef['blacklist'])) { return true; } if ($colDef['whitelist'] === '*' || in_array($column, $colDef['whitelist'])) { return false; } return true; } /** * Perform sorting of columns. * * @return void */ public function ordering(): void { if ($this->orderCallback) { call_user_func_array($this->orderCallback, $this->resolveCallbackParameter()); } else { $this->defaultOrdering(); } } /** * Resolve callback parameter instance. * * @return array<int|string, mixed> */ abstract protected function resolveCallbackParameter(); /** * Perform default query orderBy clause. * * @return void */ abstract protected function defaultOrdering(): void; /** * 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): static { $this->autoFilter = $globalSearch; $this->filterCallback = $callback; return $this; } /** * 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(); } /** * Add a search pane options on response. * * @param string $column * @param mixed $options * @param callable|null $builder * @return $this */ public function searchPane($column, $options, callable $builder = null): static { $options = value($options); if ($options instanceof Arrayable) { $options = $options->toArray(); } $this->searchPanes[$column]['options'] = $options; $this->searchPanes[$column]['builder'] = $builder; return $this; } /** * Convert instance to array. * * @return array */ public function toArray(): array { return (array) $this->make()->getData(true); } /** * Perform necessary filters. * * @return void */ protected function filterRecords(): void { if ($this->autoFilter && $this->request->isSearchable()) { $this->filtering(); } if (is_callable($this->filterCallback)) { call_user_func_array($this->filterCallback, $this->resolveCallbackParameter()); } $this->columnSearch(); $this->searchPanesSearch(); $this->filteredCount(); } /** * Perform global search. * * @return void */ public function filtering(): void { $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 * @return void */ protected function smartGlobalSearch($keyword): void { 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 * @return void */ abstract protected function globalSearch(string $keyword): void; /** * Perform search using search pane values. * * @return void */ protected function searchPanesSearch(): void { // Add support for search pane. } /** * Count total items. * * @return int */ public function totalCount(): int { return $this->totalRecords ??= $this->count(); } /** * Count filtered items. * * @return int */ protected function filteredCount(): int { return $this->filteredRecords ??= $this->count(); } /** * Apply pagination. * * @return void */ protected function paginate(): void { if ($this->request->isPaginationable() && ! $this->skipPaging) { $this->paging(); } } /** * Transform output. * * @param iterable $results * @param array $processed * @return array */ protected function transform($results, $processed): array { 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 iterable $results * @param bool $object * @return array * * @throws \Exception */ protected function processResults($results, $object = false): array { $processor = new DataProcessor( $results, $this->getColumnsDefinition(), $this->templates, $this->request->start() ); return $processor->process($object); } /** * Render json response. * * @param array $data * @return \Illuminate\Http\JsonResponse */ protected function render(array $data): JsonResponse { $output = $this->attachAppends([ 'draw' => $this->request->draw(), 'recordsTotal' => $this->totalRecords, 'recordsFiltered' => $this->filteredRecords ?? 0, 'data' => $data, ]); if ($this->config->isDebugging()) { $output = $this->showDebugger($output); } foreach ($this->searchPanes as $column => $searchPane) { $output['searchPanes']['options'][$column] = $searchPane['options']; } return new JsonResponse( $output, 200, $this->config->jsonHeaders(), $this->config->jsonOptions() ); } /** * Attach custom with meta on response. * * @param array $data * @return array */ protected function attachAppends(array $data): array { return array_merge($data, $this->appends); } /** * Append debug parameters on output. * * @param array $output * @return array */ protected function showDebugger(array $output): array { $output['input'] = $this->request->all(); return $output; } /** * Return an error json response. * * @param \Exception $exception * @return \Illuminate\Http\JsonResponse * * @throws \Yajra\DataTables\Exceptions\Exception|\Exception */ protected function errorResponse(\Exception $exception) { /** @var string $error */ $error = $this->config->get('datatables.error'); $debug = $this->config->get('app.debug'); if ($error === 'throw' || (! $error && ! $debug)) { throw $exception; } $this->getLogger()->error($exception); return new JsonResponse([ 'draw' => $this->request->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): static { $this->logger = $logger; return $this; } /** * Setup search keyword. * * @param string $value * @return string */ protected function setupKeyword(string $value): string { if ($this->config->isSmartSearch()) { $keyword = '%'.$value.'%'; if ($this->config->isWildcard()) { $keyword = Helper::wildcardLikeString($value); } // remove escaping slash added on js script request return str_replace('\\', '%', $keyword); } return $value; } /** * Get column name to be use for filtering and sorting. * * @param int $index * @param bool $wantsAlias * @return string|null */ protected function getColumnName(int $index, bool $wantsAlias = false): ?string { $column = $this->request->columnName($index); if (is_null($column)) { return null; } // 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(int $index): string { $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(): string { return 'id'; } public function editOnlySelectedColumns(): static { $this->editOnlySelectedColumns = true; return $this; } } laravel-datatables-oracle/src/Facades/error_log 0000644 00000000557 15111730130 0015570 0 ustar 00 [25-Nov-2025 21:39:08 UTC] PHP Fatal error: Uncaught Error: Class "Illuminate\Support\Facades\Facade" not found in /home/fluxyjvi/public_html/project/vendor/yajra/laravel-datatables-oracle/src/Facades/DataTables.php:16 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/yajra/laravel-datatables-oracle/src/Facades/DataTables.php on line 16 laravel-datatables-oracle/src/Facades/DataTables.php 0000644 00000001147 15111730130 0016364 0 ustar 00 <?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'; } } laravel-datatables-oracle/src/lumen.php 0000644 00000001040 15111730130 0014142 0 ustar 00 <?php if (! function_exists('config_path')) { /** * Get the configuration path. * * @param string $path * @return string */ function config_path($path = '') { return app()->basePath().'/config'.($path ? '/'.$path : $path); } } if (! function_exists('public_path')) { /** * Return the path to public dir. * * @param null $path * @return string */ function public_path($path = null) { return rtrim(app()->basePath('public/'.$path), '/'); } } laravel-datatables-oracle/src/QueryDataTable.php 0000644 00000075664 15111730130 0015720 0 ustar 00 <?php namespace Yajra\DataTables; use Illuminate\Contracts\Database\Eloquent\Builder as EloquentBuilder; use Illuminate\Contracts\Database\Query\Builder as QueryBuilder; use Illuminate\Database\Connection; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Query\Expression; use Illuminate\Http\JsonResponse; use Illuminate\Support\Collection; use Illuminate\Support\Facades\DB; use Illuminate\Support\Str; use Yajra\DataTables\Utilities\Helper; class QueryDataTable extends DataTableAbstract { /** * Builder object. * * @var QueryBuilder */ protected QueryBuilder $query; /** * Flag for ordering NULLS LAST option. * * @var bool */ protected bool $nullsLast = false; /** * Flag to check if query preparation was already done. * * @var bool */ protected bool $prepared = false; /** * Query callback for custom pagination using limit without offset. * * @var callable|null */ protected $limitCallback = null; /** * Flag to keep the select bindings. * * @var bool */ protected bool $keepSelectBindings = false; /** * Flag to ignore the selects in count query. * * @var bool */ protected bool $ignoreSelectInCountQuery = false; /** * Enable scout search and use this model for searching. * * @var Model|null */ protected ?Model $scoutModel = null; /** * Maximum number of hits to return from scout. * * @var int */ protected int $scoutMaxHits = 1000; /** * Add dynamic filters to scout search. * * @var callable|null */ protected $scoutFilterCallback = null; /** * Flag if scout search was performed. * * @var bool */ protected bool $scoutSearched = false; /** * Scout index name. * * @var string */ protected string $scoutIndex; /** * Scout key name. * * @var string */ protected string $scoutKey; /** * Flag to disable user ordering if a fixed ordering was performed (e.g. scout search). * Only works with corresponding javascript listener. * * @var bool */ protected $disableUserOrdering = false; /** * @param QueryBuilder $builder */ public function __construct(QueryBuilder $builder) { $this->query = $builder; $this->request = app('datatables.request'); $this->config = app('datatables.config'); $this->columns = $builder->columns; if ($this->config->isDebugging()) { $this->getConnection()->enableQueryLog(); } } /** * @return \Illuminate\Database\Connection */ public function getConnection(): Connection { /** @var Connection $connection */ $connection = $this->query->getConnection(); return $connection; } /** * Can the DataTable engine be created with these parameters. * * @param mixed $source * @return bool */ public static function canCreate($source): bool { return $source instanceof QueryBuilder && ! ($source instanceof EloquentBuilder); } /** * Organizes works. * * @param bool $mDataSupport * @return \Illuminate\Http\JsonResponse * * @throws \Exception */ public function make($mDataSupport = true): JsonResponse { try { $results = $this->prepareQuery()->results(); $processed = $this->processResults($results, $mDataSupport); $data = $this->transform($results, $processed); return $this->render($data); } catch (\Exception $exception) { return $this->errorResponse($exception); } } /** * Get paginated results. * * @return \Illuminate\Support\Collection<int, array> */ public function results(): Collection { return $this->query->get(); } /** * Prepare query by executing count, filter, order and paginate. * * @return $this */ public function prepareQuery(): static { if (! $this->prepared) { $this->totalRecords = $this->totalCount(); $this->filterRecords(); $this->ordering(); $this->paginate(); } $this->prepared = true; return $this; } /** * Counts current query. * * @return int */ public function count(): int { return $this->prepareCountQuery()->count(); } /** * Prepare count query builder. * * @return QueryBuilder */ public function prepareCountQuery(): QueryBuilder { $builder = clone $this->query; if ($this->isComplexQuery($builder)) { $builder->select(DB::raw('1 as dt_row_count')); if ($this->ignoreSelectInCountQuery || ! $this->isComplexQuery($builder)) { return $this->getConnection() ->query() ->fromRaw('('.$builder->toSql().') count_row_table') ->setBindings($builder->getBindings()); } $builder = clone $this->query; return $this->getConnection() ->query() ->fromRaw('('.$builder->toSql().') count_row_table') ->setBindings($builder->getBindings()); } $row_count = $this->wrap('row_count'); $builder->select($this->getConnection()->raw("'1' as {$row_count}")); if (! $this->keepSelectBindings) { $builder->setBindings([], 'select'); } return $builder; } /** * Check if builder query uses complex sql. * * @param QueryBuilder|EloquentBuilder $query * @return bool */ protected function isComplexQuery($query): bool { return Str::contains(Str::lower($query->toSql()), ['union', 'having', 'distinct', 'order by', 'group by']); } /** * Wrap column with DB grammar. * * @param string $column * @return string */ protected function wrap(string $column): string { return $this->getConnection()->getQueryGrammar()->wrap($column); } /** * Keep the select bindings. * * @return $this */ public function keepSelectBindings(): static { $this->keepSelectBindings = true; return $this; } /** * Perform column search. * * @return void */ protected function filterRecords(): void { $initialQuery = clone $this->query; if ($this->autoFilter && $this->request->isSearchable()) { $this->filtering(); } if (is_callable($this->filterCallback)) { call_user_func_array($this->filterCallback, $this->resolveCallbackParameter()); } $this->columnSearch(); $this->searchPanesSearch(); // If no modification between the original query and the filtered one has been made // the filteredRecords equals the totalRecords if ($this->query == $initialQuery) { $this->filteredRecords ??= $this->totalRecords; } else { $this->filteredCount(); } } /** * Perform column search. * * @return void */ public function columnSearch(): void { $columns = $this->request->columns(); foreach ($columns as $index => $column) { $column = $this->getColumnName($index); if (is_null($column)) { continue; } if (! $this->request->isColumnSearchable($index) || $this->isBlacklisted($column) && ! $this->hasFilterColumn($column)) { continue; } if ($this->hasFilterColumn($column)) { $keyword = $this->getColumnSearchKeyword($index, true); $this->applyFilterColumn($this->getBaseQueryBuilder(), $column, $keyword); } else { $column = $this->resolveRelationColumn($column); $keyword = $this->getColumnSearchKeyword($index); $this->compileColumnSearch($index, $column, $keyword); } } } /** * Check if column has custom filter handler. * * @param string $columnName * @return bool */ public function hasFilterColumn(string $columnName): bool { return isset($this->columnDef['filter'][$columnName]); } /** * Get column keyword to use for search. * * @param int $i * @param bool $raw * @return string */ protected function getColumnSearchKeyword(int $i, bool $raw = false): string { $keyword = $this->request->columnKeyword($i); if ($raw || $this->request->isRegex($i)) { return $keyword; } return $this->setupKeyword($keyword); } protected function getColumnNameByIndex(int $index): string { $name = (isset($this->columns[$index]) && $this->columns[$index] != '*') ? $this->columns[$index] : $this->getPrimaryKeyName(); if ($name instanceof Expression) { $name = $name->getValue($this->query->getGrammar()); } return in_array($name, $this->extraColumns, true) ? $this->getPrimaryKeyName() : $name; } /** * Apply filterColumn api search. * * @param QueryBuilder $query * @param string $columnName * @param string $keyword * @param string $boolean * @return void */ protected function applyFilterColumn($query, string $columnName, string $keyword, string $boolean = 'and'): void { $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); /** @var \Illuminate\Database\Query\Builder $baseQueryBuilder */ $baseQueryBuilder = $this->getBaseQueryBuilder($builder); $query->addNestedWhereQuery($baseQueryBuilder, $boolean); } /** * Get the base query builder instance. * * @param QueryBuilder|EloquentBuilder|null $instance * @return QueryBuilder */ protected function getBaseQueryBuilder($instance = null) { if (! $instance) { $instance = $this->query; } if ($instance instanceof EloquentBuilder) { return $instance->getQuery(); } return $instance; } /** * Get query builder instance. * * @return QueryBuilder */ public function getQuery(): QueryBuilder { return $this->query; } /** * Resolve the proper column name be used. * * @param string $column * @return string */ protected function resolveRelationColumn(string $column): string { return $column; } /** * Compile queries for column search. * * @param int $i * @param string $column * @param string $keyword * @return void */ protected function compileColumnSearch(int $i, string $column, string $keyword): void { if ($this->request->isRegex($i)) { $this->regexColumnSearch($column, $keyword); } else { $this->compileQuerySearch($this->query, $column, $keyword, ''); } } /** * Compile regex query column search. * * @param string $column * @param string $keyword * @return void */ protected function regexColumnSearch(string $column, string $keyword): void { $column = $this->wrap($column); switch ($this->getConnection()->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(string $column): string { switch ($this->getConnection()->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 QueryBuilder|EloquentBuilder $query * @param string $column * @param string $keyword * @param string $boolean * @return void */ protected function compileQuerySearch($query, string $column, string $keyword, string $boolean = 'or'): void { $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 QueryBuilder|EloquentBuilder $query * @param string $column * @return string */ protected function addTablePrefix($query, string $column): string { if (! str_contains($column, '.')) { $q = $this->getBaseQueryBuilder($query); $from = $q->from; /** @phpstan-ignore-next-line */ if (! $from instanceof Expression) { if (str_contains($from, ' as ')) { $from = explode(' as ', $from)[1]; } $column = $from.'.'.$column; } } return $this->wrap($column); } /** * Prepare search keyword based on configurations. * * @param string $keyword * @return string */ protected function prepareKeyword(string $keyword): string { if ($this->config->isCaseInsensitive()) { $keyword = Str::lower($keyword); } if ($this->config->isStartsWithSearch()) { return "$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): static { $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 = []): static { foreach ($columns as $column) { $this->orderColumn($column, str_replace(':column', $column, $sql), $bindings); } return $this; } /** * Override default column ordering. * * @param string $column * @param string|\Closure $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 = []): static { $this->columnDef['order'][$column] = compact('sql', 'bindings'); return $this; } /** * Set datatables to do ordering with NULLS LAST option. * * @return $this */ public function orderByNullsLast(): static { $this->nullsLast = true; return $this; } /** * Perform pagination. * * @return void */ public function paging(): void { $start = $this->request->start(); $length = $this->request->length(); $limit = $length > 0 ? $length : 10; if (is_callable($this->limitCallback)) { $this->query->limit($limit); call_user_func_array($this->limitCallback, [$this->query]); } else { $this->query->skip($start)->take($limit); } } /** * Paginate dataTable using limit without offset * with additional where clause via callback. * * @param callable $callback * @return $this */ public function limit(callable $callback): static { $this->limitCallback = $callback; return $this; } /** * Add column in collection. * * @param string $name * @param string|callable $content * @param bool|int $order * @return $this */ public function addColumn($name, $content, $order = false): static { $this->pushToBlacklist($name); return parent::addColumn($name, $content, $order); } /** * Perform search using search pane values. * * @return void * * @throws \Psr\Container\ContainerExceptionInterface * @throws \Psr\Container\NotFoundExceptionInterface */ protected function searchPanesSearch(): void { /** @var string[] $columns */ $columns = $this->request->get('searchPanes', []); foreach ($columns as $column => $values) { if ($this->isBlacklisted($column)) { continue; } if ($this->searchPanes[$column] && $callback = $this->searchPanes[$column]['builder']) { $callback($this->query, $values); } else { $this->query->whereIn($column, $values); } } } /** * Resolve callback parameter instance. * * @return array<int|string, mixed> */ protected function resolveCallbackParameter(): array { return [$this->query, $this->scoutSearched]; } /** * Perform default query orderBy clause. * * @return void * * @throws \Psr\Container\ContainerExceptionInterface * @throws \Psr\Container\NotFoundExceptionInterface */ protected function defaultOrdering(): void { 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($orderable['name'])) { $this->applyOrderColumn($orderable['name'], $orderable); } elseif ($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(string $column): bool { return isset($this->columnDef['order'][$column]); } /** * Apply orderColumn custom query. * * @param string $column * @param array $orderable */ protected function applyOrderColumn(string $column, array $orderable): void { $sql = $this->columnDef['order'][$column]['sql']; if ($sql === false) { return; } 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 * * @throws \Psr\Container\ContainerExceptionInterface * @throws \Psr\Container\NotFoundExceptionInterface */ protected function getNullsLastSql($column, $direction): string { /** @var string $sql */ $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 * @return void */ protected function globalSearch(string $keyword): void { // Try scout search first & fall back to default search if disabled/failed if ($this->applyScoutSearch($keyword)) { return; } $this->query->where(function ($query) use ($keyword) { collect($this->request->searchableColumnIndex()) ->map(function ($index) { return $this->getColumnName($index); }) ->filter() ->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); } }); }); } /** * Append debug parameters on output. * * @param array $output * @return array */ protected function showDebugger(array $output): array { $query_log = $this->getConnection()->getQueryLog(); array_walk_recursive($query_log, function (&$item) { if (is_string($item)) { $item = iconv('iso-8859-1', 'utf-8', $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): array { $appends = []; foreach ($this->appends as $key => $value) { if (is_callable($value)) { $appends[$key] = value($value($this->getFilteredQuery())); } else { $appends[$key] = $value; } } // Set flag to disable ordering $appends['disableOrdering'] = $this->disableUserOrdering; return array_merge($data, $appends); } /** * Get filtered, ordered and paginated query. * * @return QueryBuilder */ public function getFilteredQuery(): QueryBuilder { $this->prepareQuery(); return $this->getQuery(); } /** * Ignore the selects in count query. * * @return $this */ public function ignoreSelectsInCountQuery(): static { $this->ignoreSelectInCountQuery = true; return $this; } /** * Perform sorting of columns. * * @return void */ public function ordering(): void { // Skip if user ordering is disabled (e.g. scout search) if ($this->disableUserOrdering) { return; } parent::ordering(); } /** * Enable scout search and use provided model for searching. * $max_hits is the maximum number of hits to return from scout. * * @param string $model * @param int $max_hits * @return $this * @throws \Exception */ public function enableScoutSearch(string $model, int $max_hits = 1000): static { $scout_model = new $model; if (! class_exists($model) || ! ($scout_model instanceof Model)) { throw new \Exception("$model must be an Eloquent Model."); } if (! method_exists($scout_model, 'searchableAs') || ! method_exists($scout_model, 'getScoutKeyName')) { throw new \Exception("$model must use the Searchable trait."); } $this->scoutModel = $scout_model; $this->scoutMaxHits = $max_hits; $this->scoutIndex = $this->scoutModel->searchableAs(); $this->scoutKey = $this->scoutModel->getScoutKeyName(); return $this; } /** * Add dynamic filters to scout search. * * @param callable $callback * @return $this */ public function scoutFilter(callable $callback): static { $this->scoutFilterCallback = $callback; return $this; } /** * Apply scout search to query if enabled. * * @param string $search_keyword * @return bool */ protected function applyScoutSearch(string $search_keyword): bool { if ($this->scoutModel == null) { return false; } try { // Perform scout search $search_filters = ''; if (is_callable($this->scoutFilterCallback)) { $search_filters = ($this->scoutFilterCallback)($search_keyword); } $search_results = $this->performScoutSearch($search_keyword, $search_filters); // Apply scout search results to query $this->query->where(function ($query) use ($search_results) { $this->query->whereIn($this->scoutKey, $search_results); }); // Order by scout search results & disable user ordering (if db driver is supported) if (count($search_results) > 0 && $this->applyFixedOrderingToQuery($this->scoutKey, $search_results)) { // Disable user ordering because we already ordered by search relevancy $this->disableUserOrdering = true; } $this->scoutSearched = true; return true; } catch (\Exception) { // Scout search failed, fallback to default search return false; } } /** * Apply fixed ordering to query by a fixed set of values depending on database driver (used for scout search). * * Currently supported drivers: MySQL * * @param string $keyName * @param array $orderedKeys * @return bool */ protected function applyFixedOrderingToQuery(string $keyName, array $orderedKeys) { $connection = $this->getConnection(); $driverName = $connection->getDriverName(); // Escape keyName and orderedKeys $keyName = $connection->getQueryGrammar()->wrap($keyName); $orderedKeys = collect($orderedKeys) ->map(function ($value) use ($connection) { return $connection->escape($value); }); switch ($driverName) { case 'mysql': $this->query->orderByRaw("FIELD($keyName, ".$orderedKeys->implode(',').')'); return true; case 'pgsql': case 'oracle': $this->query->orderByRaw( 'CASE ' . $orderedKeys ->map(fn ($value, $index) => "WHEN $keyName=$value THEN $index") ->implode(' ') . ' END' ); return true; case 'sqlite': case 'sqlsrv': $this->query->orderByRaw( "CASE $keyName " . $orderedKeys ->map(fn ($value, $index) => "WHEN $value THEN $index") ->implode(' ') . ' END' ); return true; default: return false; } } /** * Perform a scout search with the configured engine and given parameters. Return matching model IDs. * * @param string $searchKeyword * @param mixed $searchFilters * @return array * @throws \Exception */ protected function performScoutSearch(string $searchKeyword, mixed $searchFilters = []): array { if (! class_exists('\Laravel\Scout\EngineManager')) { throw new \Exception('Laravel Scout is not installed.'); } $engine = app(\Laravel\Scout\EngineManager::class)->engine(); if ($engine instanceof \Laravel\Scout\Engines\MeilisearchEngine) { /** @var \Meilisearch\Client $engine */ $search_results = $engine ->index($this->scoutIndex) ->rawSearch($searchKeyword, [ 'limit' => $this->scoutMaxHits, 'attributesToRetrieve' => [$this->scoutKey], 'filter' => $searchFilters, ]); /** @var array<int, array<string, mixed>> $hits */ $hits = $search_results['hits'] ?? []; return collect($hits) ->pluck($this->scoutKey) ->all(); } elseif ($engine instanceof \Laravel\Scout\Engines\AlgoliaEngine) { /** @var \Algolia\AlgoliaSearch\SearchClient $engine */ $algolia = $engine->initIndex($this->scoutIndex); $search_results = $algolia->search($searchKeyword, [ 'offset' => 0, 'length' => $this->scoutMaxHits, 'attributesToRetrieve' => [$this->scoutKey], 'attributesToHighlight' => [], 'filters' => $searchFilters, ]); /** @var array<int, array<string, mixed>> $hits */ $hits = $search_results['hits'] ?? []; return collect($hits) ->pluck($this->scoutKey) ->all(); } else { throw new \Exception('Unsupported Scout Engine. Currently supported: Meilisearch, Algolia'); } } } laravel-datatables-oracle/src/error_log 0000644 00000015216 15111730130 0014240 0 ustar 00 [18-Nov-2025 20:45:08 UTC] PHP Fatal error: Uncaught Error: Class "Yajra\DataTables\DataTableAbstract" not found in /home/fluxyjvi/public_html/project/vendor/yajra/laravel-datatables-oracle/src/CollectionDataTable.php:14 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/yajra/laravel-datatables-oracle/src/CollectionDataTable.php on line 14 [18-Nov-2025 20:47:48 UTC] PHP Fatal error: Uncaught Error: Class "Yajra\DataTables\QueryDataTable" not found in /home/fluxyjvi/public_html/project/vendor/yajra/laravel-datatables-oracle/src/EloquentDataTable.php:18 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/yajra/laravel-datatables-oracle/src/EloquentDataTable.php on line 18 [18-Nov-2025 20:50:24 UTC] PHP Fatal error: Trait "Illuminate\Support\Traits\Macroable" not found in /home/fluxyjvi/public_html/project/vendor/yajra/laravel-datatables-oracle/src/DataTableAbstract.php on line 25 [18-Nov-2025 20:52:19 UTC] PHP Fatal error: Uncaught Error: Class "Yajra\DataTables\CollectionDataTable" not found in /home/fluxyjvi/public_html/project/vendor/yajra/laravel-datatables-oracle/src/ApiResourceDataTable.php:7 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/yajra/laravel-datatables-oracle/src/ApiResourceDataTable.php on line 7 [18-Nov-2025 20:53:19 UTC] PHP Fatal error: Uncaught Error: Class "Yajra\DataTables\DataTableAbstract" not found in /home/fluxyjvi/public_html/project/vendor/yajra/laravel-datatables-oracle/src/QueryDataTable.php:16 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/yajra/laravel-datatables-oracle/src/QueryDataTable.php on line 16 [18-Nov-2025 21:50:24 UTC] PHP Fatal error: Uncaught Error: Class "Illuminate\Support\ServiceProvider" not found in /home/fluxyjvi/public_html/project/vendor/yajra/laravel-datatables-oracle/src/DataTablesServiceProvider.php:10 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/yajra/laravel-datatables-oracle/src/DataTablesServiceProvider.php on line 10 [19-Nov-2025 04:11:56 UTC] PHP Fatal error: Trait "Illuminate\Support\Traits\Macroable" not found in /home/fluxyjvi/public_html/project/vendor/yajra/laravel-datatables-oracle/src/DataTableAbstract.php on line 25 [19-Nov-2025 04:12:08 UTC] PHP Fatal error: Uncaught Error: Class "Yajra\DataTables\DataTableAbstract" not found in /home/fluxyjvi/public_html/project/vendor/yajra/laravel-datatables-oracle/src/CollectionDataTable.php:14 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/yajra/laravel-datatables-oracle/src/CollectionDataTable.php on line 14 [19-Nov-2025 04:12:12 UTC] PHP Fatal error: Uncaught Error: Class "Yajra\DataTables\QueryDataTable" not found in /home/fluxyjvi/public_html/project/vendor/yajra/laravel-datatables-oracle/src/EloquentDataTable.php:18 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/yajra/laravel-datatables-oracle/src/EloquentDataTable.php on line 18 [19-Nov-2025 04:13:05 UTC] PHP Fatal error: Uncaught Error: Class "Yajra\DataTables\CollectionDataTable" not found in /home/fluxyjvi/public_html/project/vendor/yajra/laravel-datatables-oracle/src/ApiResourceDataTable.php:7 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/yajra/laravel-datatables-oracle/src/ApiResourceDataTable.php on line 7 [19-Nov-2025 04:15:36 UTC] PHP Fatal error: Uncaught Error: Class "Yajra\DataTables\DataTableAbstract" not found in /home/fluxyjvi/public_html/project/vendor/yajra/laravel-datatables-oracle/src/QueryDataTable.php:16 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/yajra/laravel-datatables-oracle/src/QueryDataTable.php on line 16 [19-Nov-2025 05:00:38 UTC] PHP Fatal error: Uncaught Error: Class "Illuminate\Support\ServiceProvider" not found in /home/fluxyjvi/public_html/project/vendor/yajra/laravel-datatables-oracle/src/DataTablesServiceProvider.php:10 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/yajra/laravel-datatables-oracle/src/DataTablesServiceProvider.php on line 10 [19-Nov-2025 18:45:08 UTC] PHP Fatal error: Trait "Illuminate\Support\Traits\Macroable" not found in /home/fluxyjvi/public_html/project/vendor/yajra/laravel-datatables-oracle/src/DataTables.php on line 11 [20-Nov-2025 01:15:24 UTC] PHP Fatal error: Trait "Illuminate\Support\Traits\Macroable" not found in /home/fluxyjvi/public_html/project/vendor/yajra/laravel-datatables-oracle/src/DataTables.php on line 11 [25-Nov-2025 02:56:39 UTC] PHP Fatal error: Trait "Illuminate\Support\Traits\Macroable" not found in /home/fluxyjvi/public_html/project/vendor/yajra/laravel-datatables-oracle/src/DataTableAbstract.php on line 25 [25-Nov-2025 03:02:06 UTC] PHP Fatal error: Uncaught Error: Class "Yajra\DataTables\CollectionDataTable" not found in /home/fluxyjvi/public_html/project/vendor/yajra/laravel-datatables-oracle/src/ApiResourceDataTable.php:7 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/yajra/laravel-datatables-oracle/src/ApiResourceDataTable.php on line 7 [25-Nov-2025 04:33:01 UTC] PHP Fatal error: Uncaught Error: Class "Yajra\DataTables\DataTableAbstract" not found in /home/fluxyjvi/public_html/project/vendor/yajra/laravel-datatables-oracle/src/CollectionDataTable.php:14 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/yajra/laravel-datatables-oracle/src/CollectionDataTable.php on line 14 [25-Nov-2025 05:26:10 UTC] PHP Fatal error: Trait "Illuminate\Support\Traits\Macroable" not found in /home/fluxyjvi/public_html/project/vendor/yajra/laravel-datatables-oracle/src/DataTables.php on line 11 [25-Nov-2025 05:26:17 UTC] PHP Fatal error: Uncaught Error: Class "Illuminate\Support\ServiceProvider" not found in /home/fluxyjvi/public_html/project/vendor/yajra/laravel-datatables-oracle/src/DataTablesServiceProvider.php:10 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/yajra/laravel-datatables-oracle/src/DataTablesServiceProvider.php on line 10 [25-Nov-2025 05:27:08 UTC] PHP Fatal error: Uncaught Error: Class "Yajra\DataTables\QueryDataTable" not found in /home/fluxyjvi/public_html/project/vendor/yajra/laravel-datatables-oracle/src/EloquentDataTable.php:18 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/yajra/laravel-datatables-oracle/src/EloquentDataTable.php on line 18 [25-Nov-2025 05:29:14 UTC] PHP Fatal error: Uncaught Error: Class "Yajra\DataTables\DataTableAbstract" not found in /home/fluxyjvi/public_html/project/vendor/yajra/laravel-datatables-oracle/src/QueryDataTable.php:16 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/yajra/laravel-datatables-oracle/src/QueryDataTable.php on line 16 laravel-datatables-oracle/src/DataTables.php 0000644 00000013005 15111730130 0015032 0 ustar 00 <?php namespace Yajra\DataTables; use Illuminate\Contracts\Database\Eloquent\Builder as EloquentBuilder; use Illuminate\Contracts\Database\Query\Builder as QueryBuilder; use Illuminate\Support\Traits\Macroable; use Yajra\DataTables\Exceptions\Exception; use Yajra\DataTables\Html\Builder; class DataTables { use Macroable; /** * DataTables request object. * * @var \Yajra\DataTables\Utilities\Request */ protected Utilities\Request $request; /** * HTML builder instance. * * @var \Yajra\DataTables\Html\Builder|null */ protected ?Builder $html = null; /** * Make a DataTable instance from source. * Alias of make for backward compatibility. * * @param object $source * @return DataTableAbstract * * @throws \Exception */ public static function of($source) { return self::make($source); } /** * Make a DataTable instance from source. * * @param object $source * @return DataTableAbstract * * @throws \Yajra\DataTables\Exceptions\Exception */ public static function make($source) { $engines = (array) config('datatables.engines'); $builders = (array) config('datatables.builders'); $args = func_get_args(); foreach ($builders as $class => $engine) { if ($source instanceof $class) { $callback = [$engines[$engine], 'create']; if (is_callable($callback)) { /** @var \Yajra\DataTables\DataTableAbstract $instance */ $instance = call_user_func_array($callback, $args); return $instance; } } } foreach ($engines as $engine) { $canCreate = [$engine, 'canCreate']; if (is_callable($canCreate) && call_user_func_array($canCreate, $args)) { $create = [$engine, 'create']; if (is_callable($create)) { /** @var \Yajra\DataTables\DataTableAbstract $instance */ $instance = call_user_func_array($create, $args); return $instance; } } } 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'); } /** * DataTables using Query. * * @param QueryBuilder $builder * @return \Yajra\DataTables\QueryDataTable */ public function query(QueryBuilder $builder): QueryDataTable { /** @var string */ $dataTable = config('datatables.engines.query'); $this->validateDataTable($dataTable, QueryDataTable::class); return $dataTable::create($builder); } /** * DataTables using Eloquent Builder. * * @param \Illuminate\Contracts\Database\Eloquent\Builder $builder * @return \Yajra\DataTables\EloquentDataTable */ public function eloquent(EloquentBuilder $builder): EloquentDataTable { /** @var string */ $dataTable = config('datatables.engines.eloquent'); $this->validateDataTable($dataTable, EloquentDataTable::class); return $dataTable::create($builder); } /** * DataTables using Collection. * * @param \Illuminate\Support\Collection<array-key, array>|array $collection * @return \Yajra\DataTables\CollectionDataTable */ public function collection($collection): CollectionDataTable { /** @var string */ $dataTable = config('datatables.engines.collection'); $this->validateDataTable($dataTable, CollectionDataTable::class); return $dataTable::create($collection); } /** * DataTables using Collection. * * @param \Illuminate\Http\Resources\Json\AnonymousResourceCollection<array-key, array>|array $resource * @return ApiResourceDataTable|DataTableAbstract */ public function resource($resource) { return ApiResourceDataTable::create($resource); } /** * Get html builder instance. * * @return \Yajra\DataTables\Html\Builder * * @throws \Yajra\DataTables\Exceptions\Exception */ public function getHtmlBuilder() { if (! class_exists(Builder::class)) { throw new Exception('Please install yajra/laravel-datatables-html to be able to use this function.'); } return $this->html ?: $this->html = app('datatables.html'); } /** * @param string $engine * @param string $parent * @return void * * @throws \Yajra\DataTables\Exceptions\Exception */ public function validateDataTable(string $engine, string $parent): void { if (! ($engine == $parent || is_subclass_of($engine, $parent))) { $this->throwInvalidEngineException($engine, $parent); } } /** * @param string $engine * @param string $parent * @return void * * @throws \Yajra\DataTables\Exceptions\Exception */ public function throwInvalidEngineException(string $engine, string $parent): void { throw new Exception("The given datatable engine `{$engine}` is not compatible with `{$parent}`."); } } laravel-datatables-oracle/src/config/datatables.php 0000644 00000010020 15111730130 0016371 0 ustar 00 <?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 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, ], /* * Default condition to determine if a parameter is a callback or not. * Callbacks needs to start by those terms, or they will be cast to string. */ 'callback' => ['$', '$.', 'function'], ]; laravel-datatables-oracle/src/config/error_log 0000644 00000000532 15111730130 0015500 0 ustar 00 [25-Nov-2025 20:02:07 UTC] PHP Fatal error: Uncaught Error: Call to undefined function env() in /home/fluxyjvi/public_html/project/vendor/yajra/laravel-datatables-oracle/src/config/datatables.php:79 Stack trace: #0 {main} thrown in /home/fluxyjvi/public_html/project/vendor/yajra/laravel-datatables-oracle/src/config/datatables.php on line 79 laravel-datatables-oracle/src/ApiResourceDataTable.php 0000644 00000002666 15111730130 0017024 0 ustar 00 <?php namespace Yajra\DataTables; use Illuminate\Http\Resources\Json\AnonymousResourceCollection; class ApiResourceDataTable extends CollectionDataTable { /** * 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<array-key, array>|array $source * @return ApiResourceDataTable|DataTableAbstract */ public static function create($source) { return parent::create($source); } /** * CollectionEngine constructor. * * @param \Illuminate\Http\Resources\Json\AnonymousResourceCollection<array-key, array> $resourceCollection */ public function __construct(AnonymousResourceCollection $resourceCollection) { /** @var \Illuminate\Support\Collection<(int|string), array> $collection */ $collection = collect($resourceCollection)->pluck('resource'); $this->request = app('datatables.request'); $this->config = app('datatables.config'); $this->collection = $collection; $this->original = $collection; $this->columns = array_keys($this->serialize($collection->first())); } } laravel-datatables-oracle/README.md 0000644 00000012720 15111730130 0013010 0 ustar 00 # jQuery DataTables API for Laravel 4|5|6|7|8|9|10 [](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) [](https://github.com/yajra/laravel-datatables/actions/workflows/continuous-integration.yml) [](https://github.com/yajra/laravel-datatables/actions/workflows/static-analysis.yml) [](https://packagist.org/packages/yajra/laravel-datatables-oracle) [](https://packagist.org/packages/yajra/laravel-datatables-oracle) Laravel package for handling [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 return datatables()->eloquent(User::query())->toJson(); return datatables()->query(DB::table('users'))->toJson(); return datatables()->collection(User::all())->toJson(); return datatables(User::query())->toJson(); return datatables(DB::table('users'))->toJson(); return datatables(User::all())->toJson(); ``` ## Sponsors <a href="https://editor.datatables.net?utm_source=laravel-datatables&utm_medium=github_readme&utm_campaign=logo"> <img src="http://datatables.net/media/images/logo.png" alt="DataTables" height="64"> </a> <a href="https://jb.gg/OpenSourceSupport"> <img src="https://resources.jetbrains.com/storage/products/company/brand/logos/jb_beam.png" alt="JetBrains.com" height="128"> </a> <a href="https://blackfire.io/docs/introduction?utm_source=laravel-datatables&utm_medium=github_readme&utm_campaign=logo"> <img src="https://i.imgur.com/zR8rsqk.png" alt="Blackfire.io" height="64"> </a> ## Requirements - [PHP >= 8.0.2](http://php.net/) - [Laravel Framework](https://github.com/laravel/framework) - [jQuery DataTables v1.10.x](http://datatables.net/) ## Documentations - [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) ## 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 | | 8.x.x | 9.x | | 9.x.x | 10.x | | 10.x.x | 10.x | ## Quick Installation ```bash composer require yajra/laravel-datatables-oracle:"^10.0" ``` #### Service Provider & Facade (Optional on Laravel 5.5+) Register provider and facade on your `config/app.php` file. ```php 'providers' => [ ..., Yajra\DataTables\DataTablesServiceProvider::class, ] 'aliases' => [ ..., 'DataTables' => Yajra\DataTables\Facades\DataTables::class, ] ``` #### Configuration (Optional) ```bash php artisan vendor:publish --provider="Yajra\DataTables\DataTablesServiceProvider" ``` And that's it! Start building out some awesome DataTables! ## 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. ## Security If you discover any security related issues, please email [aqangeles@gmail.com](mailto:aqangeles@gmail.com) instead of using the issue tracker. ## Credits - [Arjay Angeles](https://github.com/yajra) - [bllim/laravel4-datatables-package](https://github.com/bllim/laravel4-datatables-package) - [All Contributors](https://github.com/yajra/laravel-datatables/graphs/contributors) ## License The MIT License (MIT). Please see [License File](https://github.com/yajra/laravel-datatables/blob/master/LICENSE.md) for more information. laravel-datatables-oracle/CONDUCT.md 0000644 00000012243 15111730130 0013152 0 ustar 00 # Contributor Covenant Code of Conduct ## Our Pledge We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, caste, color, religion, or sexual identity and orientation. We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community. ## Our Standards Examples of behavior that contributes to a positive environment for our community include: * Demonstrating empathy and kindness toward other people * Being respectful of differing opinions, viewpoints, and experiences * Giving and gracefully accepting constructive feedback * Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience * Focusing on what is best not just for us as individuals, but for the overall community Examples of unacceptable behavior include: * The use of sexualized language or imagery, and sexual attention or advances of any kind * Trolling, insulting or derogatory comments, and personal or political attacks * Public or private harassment * Publishing others’ private information, such as a physical or email address, without their explicit permission * Other conduct which could reasonably be considered inappropriate in a professional setting ## Enforcement Responsibilities Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful. Community leaders 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, and will communicate reasons for moderation decisions when appropriate. ## Scope This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. ## Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at [INSERT CONTACT METHOD]. All complaints will be reviewed and investigated promptly and fairly. All community leaders are obligated to respect the privacy and security of the reporter of any incident. ## Enforcement Guidelines Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct: ### 1. Correction Community Impact: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community. Consequence: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested. ### 2. Warning Community Impact: A violation through a single incident or series of actions. Consequence: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban. ### 3. Temporary Ban Community Impact: A serious violation of community standards, including sustained inappropriate behavior. Consequence: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban. ### 4. Permanent Ban Community Impact: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals. Consequence: A permanent ban from any sort of public interaction within the community. ## Attribution This Code of Conduct is adapted from the Contributor Covenant, version 2.1, available at https://www.contributor-covenant.org/version/2/1/code_of_conduct.html. Community Impact Guidelines were inspired by Mozilla’s code of conduct enforcement ladder. For answers to common questions about this code of conduct, see the FAQ at https://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations. For answers to common questions about this code of conduct, see the FAQ at https://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations. laravel-datatables-oracle/sonar-project.properties 0000644 00000000143 15111730130 0016431 0 ustar 00 # Define separate root directories for sources and tests sonar.sources = src/ sonar.tests = tests/ laravel-datatables-oracle/composer.json 0000644 00000004053 15111730130 0014253 0 ustar 00 { "name": "yajra/laravel-datatables-oracle", "description": "jQuery DataTables API for Laravel 4|5|6|7|8|9|10", "keywords": [ "laravel", "dataTables", "jquery" ], "license": "MIT", "authors": [ { "name": "Arjay Angeles", "email": "aqangeles@gmail.com" } ], "require": { "php": "^8.0.2", "illuminate/database": "^9|^10", "illuminate/filesystem": "^9|^10", "illuminate/http": "^9|^10", "illuminate/support": "^9|^10", "illuminate/view": "^9|^10" }, "require-dev": { "algolia/algoliasearch-client-php": "^3.4", "laravel/scout": "^10.5", "meilisearch/meilisearch-php": "^1.4", "nunomaduro/larastan": "^2.4", "orchestra/testbench": "^8", "yajra/laravel-datatables-html": "^9.3.4|^10" }, "suggest": { "yajra/laravel-datatables-export": "Plugin for server-side exporting using livewire and queue worker.", "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/" }, "files": [ "src/helper.php" ] }, "autoload-dev": { "psr-4": { "Yajra\\DataTables\\Tests\\": "tests/" } }, "extra": { "branch-alias": { "dev-master": "10.x-dev" }, "laravel": { "providers": [ "Yajra\\DataTables\\DataTablesServiceProvider" ], "aliases": { "DataTables": "Yajra\\DataTables\\Facades\\DataTables" } } }, "config": { "sort-packages": true, "allow-plugins": { "php-http/discovery": true } }, "scripts": { "test": "vendor/bin/phpunit" }, "minimum-stability": "dev", "prefer-stable": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/yajra" } ] } laravel-datatables-oracle/LICENSE.md 0000644 00000002117 15111730130 0013134 0 ustar 00 (The MIT License) Copyright (c) 2013-2022 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 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. laravel-datatables-oracle/CHANGELOG.md 0000644 00000016324 15111730130 0013346 0 ustar 00 # Laravel DataTables CHANGELOG [](https://packagist.org/packages/yajra/laravel-datatables-oracle) [](https://packagist.org/packages/yajra/laravel-datatables-oracle) [](https://travis-ci.org/yajra/laravel-datatables) [](https://packagist.org/packages/yajra/laravel-datatables-oracle) [](https://packagist.org/packages/yajra/laravel-datatables-oracle) ### [Unreleased] ### [v10.11.0] - 2023-11-04 - feat: Scout Search Implementation #3082 - feat: Add scout fixed ordering for pgsql and oracle #3090 ### [v10.10.0] - 2023-10-04 - feat: allow closure on formatColumn #3073 ### [v10.9.0] - 2023-09-29 - feat: Ability to pass static data to a blade render #3067 ### [v10.8.0] - 2023-08-12 - feat: convert prepareQuery from protected to public #3045 ### [v10.7.0] - 2023-07-31 - feat: add ability to disable eloquent getter mutator #3009 - feat: Ability to use deep relations for searching #3035 ### [v10.6.2] - 2023-07-15 - fix: #3010 - convert expressions to strings #3029 ### [v10.6.1] - 2023-07-05 - fix: #3025 #3026 - fix the error introduced in 10.4.4 as described in #3025. ### [v10.6.0] - 2023-06-29 - feat: Expose autoFilter setter to disable post filtering #2981 ### [v10.5.0] - 2023-06-29 - feat: Prevent editColumn when column is not shown #3018 ### [v10.4.4] - 2023-06-27 - feat: Optimize countQuery with complex select #3008 - fix: phpstan #3022 ### [v10.4.3] - 2023-06-07 - Fix: Prevent the filteredCount() query if no filter is applied to the initial query #3007 ### [v10.4.2] - 2023-05-31 - Fix return type for setTransformer() and setSerializer() #3003 ### [v10.4.1] - 2023-05-27 - fix: Error when setting language config for "editor" #2983 ### [v10.4.0] - 2023-03-28 - feat: Allow any callable in ->addColumn() #2977 - fix: #2976 ### [v10.3.1] - 2023-02-20 - fix: Fix anonymous resource collection data formatting #2944 - fix: phpunit 10 deprecation #2955 - fix: bump orchestra/testbench to 8 #2949 ### [v10.3.0] - 2023-02-07 - Add Laravel 10 compatibility #2948 ### [v10.2.3] - 2023-01-18 - fix: Custom Order on eager loaded relationships was not working - fix #2905 ### [v10.2.2] - 2023-01-11 - fix: prevent deprecation errors in php 8.1+ #2931 - fixes #2930 ### [v10.2.1] - 2022-12-07 - fix: case insensitive starts with search #2917 #2916 ### [v10.2.0] - 2022-11-03 - PHP 8.1 Depreciation Fix #2877 - Methods pointing to the "uncustomizable" classes. #2861 ### [v10.1.6] - 2022-10-10 - Fix anonymous resource collection #2870 - Fix #2827 - Add stale workflow ### [v10.1.5] - 2022-10-06 - Fix with method error with static analysis #2865 ### [v10.1.4] - 2022-09-27 - Fixed the search column for same table relations #2856 ### [v10.1.3] - 2022-09-20 - Fix relation key name for BelongsToMany #2850 ### [v10.1.2] - 2022-07-12 - Fix HasOneThrough #2818 ### [v10.1.1] - 2022-06-24 - Fix null recordsFiltered on empty collection #2806 - Fix #2793 ### [v10.1.0] - 2022-06-21 - Add support for dependency injection when using closure. #2800 ### [v10.0.8] - 2022-06-21 - Make canCreate at QueryDataTable accept QueryBuilder only #2798 ### [v10.0.7] - 2022-05-23 - Fix create eloquent datatable from relation #2789 ### [v10.0.6] - 2022-05-18 - Added null parameter type as allowed to handle default Action column from laravel-datatables-html #2787 ### [v10.0.5] - 2022-05-17 - Fix Return value must be of type int, string returned. ### [v10.0.4] - 2022-05-08 - Fix accidental formatter issue on eloquent - Add formatColumn test for eloquent ### [v10.0.3] - 2022-05-08 - Additional fix & test for zero total records ### [v10.0.2] - 2022-05-08 - Fix set total & filtered records count https://github.com/yajra/laravel-datatables/pull/2778 - Fix set total & filtered records count - Fix #1453 #1454 #2050 #2609 - Add feature test - Deprecate `skipTotalRecords`, just use `setTotalRecords` directly. ### [v10.0.1] - 2022-05-08 - Code clean-up and several phpstan fixes ### [v10.0.0] - 2022-05-08 - Laravel DataTables v10.x to support Laravel 9.x - Added PHPStan with max level static analysis - Drop `queryBuilder()` method - Drop support for `ApiResourceDataTable` - PHP8 syntax / method signature changed [Unreleased]: https://github.com/yajra/laravel-datatables/compare/v10.11.0...10.x [v10.11.0]: https://github.com/yajra/laravel-datatables/compare/v10.11.0...v10.10.0 [v10.10.0]: https://github.com/yajra/laravel-datatables/compare/v10.10.0...v10.9.0 [v10.9.0]: https://github.com/yajra/laravel-datatables/compare/v10.9.0...v10.8.0 [v10.8.0]: https://github.com/yajra/laravel-datatables/compare/v10.8.0...v10.7.0 [v10.7.0]: https://github.com/yajra/laravel-datatables/compare/v10.7.0...v10.6.2 [v10.6.2]: https://github.com/yajra/laravel-datatables/compare/v10.6.2...v10.6.1 [v10.6.1]: https://github.com/yajra/laravel-datatables/compare/v10.6.1...v10.6.0 [v10.6.0]: https://github.com/yajra/laravel-datatables/compare/v10.6.0...v10.5.0 [v10.5.0]: https://github.com/yajra/laravel-datatables/compare/v10.5.0...v10.4.4 [v10.4.4]: https://github.com/yajra/laravel-datatables/compare/v10.4.4...v10.4.3 [v10.3.1]: https://github.com/yajra/laravel-datatables/compare/v10.3.1...v10.3.0 [v10.3.1]: https://github.com/yajra/laravel-datatables/compare/v10.3.1...v10.3.0 [v10.3.0]: https://github.com/yajra/laravel-datatables/compare/v10.3.0...v10.2.3 [v10.2.3]: https://github.com/yajra/laravel-datatables/compare/v10.2.3...v10.2.2 [v10.2.2]: https://github.com/yajra/laravel-datatables/compare/v10.2.2...v10.2.1 [v10.2.1]: https://github.com/yajra/laravel-datatables/compare/v10.2.1...v10.2.0 [v10.2.0]: https://github.com/yajra/laravel-datatables/compare/v10.2.0...v10.1.6 [v10.1.6]: https://github.com/yajra/laravel-datatables/compare/v10.1.6...v10.1.5 [v10.1.5]: https://github.com/yajra/laravel-datatables/compare/v10.1.5...v10.1.4 [v10.1.4]: https://github.com/yajra/laravel-datatables/compare/v10.1.4...v10.1.3 [v10.1.3]: https://github.com/yajra/laravel-datatables/compare/v10.1.3...v10.1.2 [v10.1.2]: https://github.com/yajra/laravel-datatables/compare/v10.1.2...v10.1.1 [v10.1.1]: https://github.com/yajra/laravel-datatables/compare/v10.1.1...v10.1.0 [v10.1.0]: https://github.com/yajra/laravel-datatables/compare/v10.1.0...v10.0.8 [v10.0.8]: https://github.com/yajra/laravel-datatables/compare/v10.0.8...v10.0.7 [v10.0.7]: https://github.com/yajra/laravel-datatables/compare/v10.0.7...v10.0.6 [v10.0.6]: https://github.com/yajra/laravel-datatables/compare/v10.0.6...v10.0.5 [v10.0.5]: https://github.com/yajra/laravel-datatables/compare/v10.0.5...v10.0.4 [v10.0.4]: https://github.com/yajra/laravel-datatables/compare/v10.0.4...v10.0.3 [v10.0.3]: https://github.com/yajra/laravel-datatables/compare/v10.0.3...v10.0.2 [v10.0.2]: https://github.com/yajra/laravel-datatables/compare/v10.0.2...v10.0.1 [v10.0.1]: https://github.com/yajra/laravel-datatables/compare/v10.0.1...v10.0.0 [v10.0.0]: https://github.com/yajra/laravel-datatables/compare/v10.0.0...10.x laravel-datatables-oracle/UPGRADE.md 0000644 00000002441 15111730130 0013141 0 ustar 00 # UPGRADE GUIDE ## Upgrading from v9.x to v10.x - `ApiResourceDataTable` support dropped, use `CollectionDataTable` instead. - `queryBuilder()` deprecated method removed, use `query()` instead. - Methods signature were updated to PHP8 syntax, adjust as needed if you extended the package. ## Upgrading from v8.x to v9.x No breaking changes with only a bump on php version requirements. ## Upgrading from v7.x to v8.x 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). ## 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`.
Simpan